Mercurial > mplayer.hg
annotate libmpdemux/demux_asf.c @ 27319:09cf111f68b8
Revert to previous dependency checking behavior.
Take included header files into account when generating dependency files.
This has problems when header files are removed or renamed, but does not
silently miscompile files.
author | diego |
---|---|
date | Sat, 26 Jul 2008 18:36:48 +0000 |
parents | 16beae919ff1 |
children | 8cc7db468b6b |
rev | line source |
---|---|
1 | 1 // ASF file parser for DEMUXER v0.3 by A'rpi/ESP-team |
2 | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
3 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
4 #include <stdlib.h> |
1430 | 5 #include <unistd.h> |
27273 | 6 #include <limits.h> |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
7 |
1567 | 8 #include "config.h" |
9 #include "mp_msg.h" | |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1628
diff
changeset
|
10 #include "help_mp.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
11 |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21968
diff
changeset
|
12 #include "stream/stream.h" |
1342 | 13 #include "asf.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
14 #include "demuxer.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
15 |
17012 | 16 #include "libvo/fastmemcpy.h" |
25488 | 17 #include "libavutil/intreadwrite.h" |
1342 | 18 |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
19 // defined at asfheader.c: |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
20 |
16175 | 21 extern int asf_check_header(demuxer_t *demuxer); |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
22 extern int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf); |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
23 |
1 | 24 // based on asf file-format doc by Eugene [http://divx.euro.ru] |
25 | |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
26 /** |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
27 * \brief reads int stored in number of bytes given by len |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
28 * \param ptr pointer to read from, is incremented appropriately |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
29 * \param len lowest 2 bits indicate number of bytes to read |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
30 * \param def default value to return if len is invalid |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
31 */ |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
32 static inline unsigned read_varlen(uint8_t **ptr, int len, int def) { |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
33 const uint8_t *p = *ptr; |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
34 len &= 3; |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
35 switch (len) { |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
36 case 1: *ptr += 1; return *p; |
25488 | 37 case 2: *ptr += 2; return AV_RL16(p); |
38 case 3: *ptr += 4; return AV_RL32(p); | |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
39 } |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
40 return def; |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
41 } |
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
42 |
25925 | 43 /** |
44 * \brief checks if there is enough data to read the bytes given by len | |
45 * \param ptr pointer to read from | |
46 * \param endptr pointer to the end of the buffer | |
47 * \param len lowest 2 bits indicate number of bytes to read | |
48 */ | |
49 static inline int check_varlen(uint8_t *ptr, uint8_t *endptr, int len) { | |
26414
a7031923e4dc
demux_asf: Fix operator precedence in packet length check
uau
parents:
26069
diff
changeset
|
50 return len&3 ? ptr + (1<<((len&3) - 1)) <= endptr : 1; |
25925 | 51 } |
52 | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
53 static void asf_descrambling(unsigned char **src,unsigned len, struct asf_priv* asf){ |
27270
44ebd7860248
Make sure demuxed ASF packet is properly padded after descrambling
reimar
parents:
27269
diff
changeset
|
54 unsigned char *dst; |
15553
43af13780751
Speedup asf descrambling (avoid one memcpy and use our fastmemcpy).
reimar
parents:
14502
diff
changeset
|
55 unsigned char *s2=*src; |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
56 unsigned i=0,x,y; |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27273
diff
changeset
|
57 if (len > UINT_MAX - MP_INPUT_BUFFER_PADDING_SIZE) |
27270
44ebd7860248
Make sure demuxed ASF packet is properly padded after descrambling
reimar
parents:
27269
diff
changeset
|
58 return; |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27273
diff
changeset
|
59 dst = malloc(len + MP_INPUT_BUFFER_PADDING_SIZE); |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
60 while(len>=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b+i){ |
1567 | 61 // mp_msg(MSGT_DEMUX,MSGL_DBG4,"descrambling! (w=%d b=%d)\n",w,asf_scrambling_b); |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
62 //i+=asf_scrambling_h*asf_scrambling_w; |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
63 for(x=0;x<asf->scrambling_w;x++) |
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
64 for(y=0;y<asf->scrambling_h;y++){ |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23357
diff
changeset
|
65 fast_memcpy(dst+i,s2+(y*asf->scrambling_w+x)*asf->scrambling_b,asf->scrambling_b); |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
66 i+=asf->scrambling_b; |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
67 } |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
68 s2+=asf->scrambling_h*asf->scrambling_w*asf->scrambling_b; |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
69 } |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23357
diff
changeset
|
70 //if(i<len) fast_memcpy(dst+i,src+i,len-i); |
15553
43af13780751
Speedup asf descrambling (avoid one memcpy and use our fastmemcpy).
reimar
parents:
14502
diff
changeset
|
71 free(*src); |
43af13780751
Speedup asf descrambling (avoid one memcpy and use our fastmemcpy).
reimar
parents:
14502
diff
changeset
|
72 *src = dst; |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
73 } |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
74 |
23239 | 75 /***************************************************************** |
76 * \brief initializes asf private data | |
77 * | |
78 */ | |
79 static void init_priv (struct asf_priv* asf){ | |
80 asf->last_vid_seq=-1; | |
81 asf->vid_ext_timing_index=-1; | |
82 asf->aud_ext_timing_index=-1; | |
83 asf->vid_ext_frame_index=-1; | |
84 } | |
85 | |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
86 static void demux_asf_append_to_packet(demux_packet_t* dp,unsigned char *data,int len,int offs) |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
87 { |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
88 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); |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27273
diff
changeset
|
89 dp->buffer=realloc(dp->buffer,dp->len+len+MP_INPUT_BUFFER_PADDING_SIZE); |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23357
diff
changeset
|
90 fast_memcpy(dp->buffer+dp->len,data,len); |
27282
16beae919ff1
Avoid including avcodec.h in demuxer.h (and thus many other files) just to get
reimar
parents:
27273
diff
changeset
|
91 memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE); |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
92 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len); |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
93 dp->len+=len; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
94 } |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
95 |
23239 | 96 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){ |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
97 struct asf_priv* asf = demux->priv; |
1 | 98 demux_stream_t *ds=NULL; |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
99 int close_seg=0; |
1 | 100 |
1567 | 101 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len); |
1 | 102 |
426 | 103 if(demux->video->id==-1) |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
104 if(demux->v_streams[id]) |
426 | 105 demux->video->id=id; |
106 | |
1 | 107 if(demux->audio->id==-1) |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
108 if(demux->a_streams[id]) |
426 | 109 demux->audio->id=id; |
1 | 110 |
111 if(id==demux->audio->id){ | |
112 // audio | |
113 ds=demux->audio; | |
426 | 114 if(!ds->sh){ |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
115 ds->sh=demux->a_streams[id]; |
1567 | 116 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected ASF audio ID = %d\n",ds->id); |
426 | 117 } |
1 | 118 } else |
119 if(id==demux->video->id){ | |
120 // video | |
121 ds=demux->video; | |
426 | 122 if(!ds->sh){ |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
123 ds->sh=demux->v_streams[id]; |
1567 | 124 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected ASF video ID = %d\n",ds->id); |
426 | 125 } |
1 | 126 } |
127 | |
128 if(ds){ | |
129 if(ds->asf_packet){ | |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
130 demux_packet_t* dp=ds->asf_packet; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
131 |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
132 if (ds==demux->video && asf->asf_is_dvr_ms) { |
23239 | 133 if (asf->new_vid_frame_seg) { |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
134 dp->pos=demux->filepos; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
135 close_seg = 1; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
136 } else seq = ds->asf_seq; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
137 } else close_seg = ds->asf_seq!=seq; |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
138 |
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
139 if(close_seg){ |
1 | 140 // closed segment, finalize packet: |
141 if(ds==demux->audio) | |
18001 | 142 if(asf->scrambling_h>1 && asf->scrambling_w>1 && asf->scrambling_b>0) |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
143 asf_descrambling(&ds->asf_packet->buffer,ds->asf_packet->len,asf); |
1 | 144 ds_add_packet(ds,ds->asf_packet); |
145 ds->asf_packet=NULL; | |
146 } else { | |
147 // append data to it! | |
18609
bb7042d74855
Patch from John Donaghy: "fix for audio and video in dvr-ms asf files"
pacman
parents:
18001
diff
changeset
|
148 demux_asf_append_to_packet(dp,data,len,offs); |
1 | 149 // we are ready now. |
150 return 1; | |
151 } | |
152 } | |
153 // create new packet: | |
154 { demux_packet_t* dp; | |
155 if(offs>0){ | |
1567 | 156 mp_msg(MSGT_DEMUX,MSGL_V,"warning! broken fragment, %d bytes missing \n",offs); |
1 | 157 return 0; |
158 } | |
159 dp=new_demux_packet(len); | |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23357
diff
changeset
|
160 fast_memcpy(dp->buffer,data,len); |
23239 | 161 if (asf->asf_is_dvr_ms) |
23469 | 162 dp->pts=time*0.0000001; |
23239 | 163 else |
23469 | 164 dp->pts=time*0.001; |
979 | 165 dp->flags=keyframe; |
1 | 166 // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); |
167 dp->pos=demux->filepos; | |
168 ds->asf_packet=dp; | |
169 ds->asf_seq=seq; | |
170 // we are ready now. | |
171 return 1; | |
172 } | |
173 } | |
174 | |
175 return 0; | |
176 } | |
177 | |
23239 | 178 /***************************************************************** |
179 * \brief read the replicated data associated with each segment | |
180 * \parameter pp reference to replicated data | |
181 * \parameter id stream number | |
182 * \parameter seq media object number | |
183 * \parameter keyframe key frame indicator - set to zero if keyframe, non-zero otherwise | |
184 * \parameter seg_time set to payload time when valid, if audio or new video frame payload, zero otherwise | |
185 * | |
186 */ | |
187 static void get_payload_extension_data(demuxer_t *demux, unsigned char** pp, unsigned char id, unsigned int seq, int *keyframe, uint64_t *seg_time){ | |
188 struct asf_priv* asf = demux->priv; | |
189 uint64_t payload_time; //100ns units | |
190 int i, ext_max, ext_timing_index; | |
191 uint8_t *pi = *pp+4; | |
192 | |
193 if(demux->video->id==-1) | |
194 if(demux->v_streams[id]) | |
195 demux->video->id=id; | |
196 | |
197 if(demux->audio->id==-1) | |
198 if(demux->a_streams[id]) | |
199 demux->audio->id=id; | |
200 | |
201 if (id!=demux->video->id && id!=demux->audio->id) return; | |
202 | |
203 if (id==demux->video->id) { | |
204 ext_max = asf->vid_repdata_count; | |
205 ext_timing_index = asf->vid_ext_timing_index; | |
206 } else { | |
207 ext_max = asf->aud_repdata_count; | |
208 ext_timing_index = asf->aud_ext_timing_index; | |
209 } | |
210 | |
211 *seg_time=0.0; | |
212 asf->new_vid_frame_seg = 0; | |
213 | |
214 for (i=0; i<ext_max; i++) { | |
215 uint16_t payextsize; | |
216 uint8_t segment_marker; | |
217 | |
218 if (id==demux->video->id) | |
219 payextsize = asf->vid_repdata_sizes[i]; | |
220 else | |
221 payextsize = asf->aud_repdata_sizes[i]; | |
222 | |
223 if (payextsize == 65535) { | |
25488 | 224 payextsize = AV_RL16(pi); |
23239 | 225 pi+=2; |
226 } | |
227 | |
228 // if this is the timing info extension then read the payload time | |
229 if (i == ext_timing_index) | |
25488 | 230 payload_time = AV_RL64(pi+8); |
23239 | 231 |
232 // if this is the video frame info extension then | |
233 // set the keyframe indicator, the 'new frame segment' indicator | |
234 // and (initially) the 'frame time' | |
235 if (i == asf->vid_ext_frame_index && id==demux->video->id) { | |
236 segment_marker = pi[0]; | |
237 // Known video stream segment_marker values that | |
238 // contain useful information: | |
239 // | |
240 // NTSC/ATSC (29.97fps): 0X4A 01001010 | |
241 // 0X4B 01001011 | |
242 // 0X49 01001001 | |
243 // | |
244 // PAL/ATSC (25fps): 0X3A 00111010 | |
245 // 0X3B 00111011 | |
246 // 0X39 00111001 | |
247 // | |
248 // ATSC progressive (29.97fps): 0X7A 01111010 | |
249 // 0X7B 01111011 | |
250 // 0X79 01111001 | |
251 // 11111111 | |
252 // ^ this is new video frame marker | |
253 // | |
254 // ^^^^ these bits indicate the framerate | |
255 // 0X4 is 29.97i, 0X3 is 25i, 0X7 is 29.97p, ???=25p | |
256 // | |
257 // ^^^ these bits indicate the frame type: | |
258 // 001 means I-frame | |
259 // 010 and 011 probably mean P and B | |
260 | |
261 asf->new_vid_frame_seg = (0X08 & segment_marker) && seq != asf->last_vid_seq; | |
262 | |
263 if (asf->new_vid_frame_seg) asf->last_vid_seq = seq; | |
264 | |
265 if (asf->avg_vid_frame_time == 0) { | |
266 // set the average frame time initially (in 100ns units). | |
267 // This is based on what works for known samples. | |
268 // It can be extended if more samples of different types can be obtained. | |
269 if (((segment_marker & 0XF0) >> 4) == 4) { | |
270 asf->avg_vid_frame_time = (uint64_t)((1.001 / 30.0) * 10000000.0); | |
271 asf->know_frame_time=1; | |
272 } else if (((segment_marker & 0XF0) >> 4) == 3) { | |
273 asf->avg_vid_frame_time = (uint64_t)(0.04 * 10000000.0); | |
274 asf->know_frame_time=1; | |
275 } else if (((segment_marker & 0XF0) >> 4) == 6) { | |
276 asf->avg_vid_frame_time = (uint64_t)(0.02 * 10000000.0); | |
277 asf->know_frame_time=1; | |
278 } else if (((segment_marker & 0XF0) >> 4) == 7) { | |
279 asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0); | |
280 asf->know_frame_time=1; | |
281 } else { | |
282 // we dont know the frame time initially so | |
283 // make a guess and then recalculate as we go. | |
284 asf->avg_vid_frame_time = (uint64_t)((1.001 / 60.0) * 10000000.0); | |
285 asf->know_frame_time=0; | |
286 } | |
287 } | |
288 *keyframe = (asf->new_vid_frame_seg && (segment_marker & 0X07) == 1); | |
289 } | |
290 pi +=payextsize; | |
291 } | |
292 | |
293 if (id==demux->video->id && asf->new_vid_frame_seg) { | |
294 asf->vid_frame_ct++; | |
295 // Some samples only have timings on key frames and | |
296 // the rest contain non-cronological timestamps. Interpolating | |
297 // the values between key frames works for all samples. | |
298 if (*keyframe) { | |
299 asf->found_first_key_frame=1; | |
300 if (!asf->know_frame_time && asf->last_key_payload_time > 0) { | |
301 // We dont know average frametime so recalculate. | |
302 // Giving precedence to the 'weight' of the existing | |
303 // average limits damage done to new value when there is | |
304 // a sudden time jump which happens occasionally. | |
305 asf->avg_vid_frame_time = | |
306 (0.9 * asf->avg_vid_frame_time) + | |
307 (0.1 * ((payload_time - asf->last_key_payload_time) / asf->vid_frame_ct)); | |
308 } | |
309 asf->last_key_payload_time = payload_time; | |
310 asf->vid_frame_ct = 1; | |
311 *seg_time = payload_time; | |
312 } else | |
313 *seg_time = (asf->last_key_payload_time + (asf->avg_vid_frame_time * (asf->vid_frame_ct-1))); | |
314 } | |
315 | |
316 if (id==demux->audio->id) { | |
317 if (payload_time != -1) | |
318 asf->last_aud_diff = payload_time - asf->last_aud_pts; | |
319 asf->last_aud_pts += asf->last_aud_diff; | |
320 *seg_time = asf->last_aud_pts; | |
321 } | |
322 } | |
1 | 323 //static int num_elementary_packets100=0; |
324 //static int num_elementary_packets101=0; | |
325 | |
326 // return value: | |
327 // 0 = EOF or no stream found | |
328 // 1 = successfully read a packet | |
16175 | 329 static int demux_asf_fill_buffer(demuxer_t *demux, demux_stream_t *ds){ |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
330 struct asf_priv* asf = demux->priv; |
1 | 331 |
332 demux->filepos=stream_tell(demux->stream); | |
3475
390388c75209
Applied the patch from Alban Bedel <albeu@free.fr> to
bertrand
parents:
2338
diff
changeset
|
333 // Brodcast stream have movi_start==movi_end |
390388c75209
Applied the patch from Alban Bedel <albeu@free.fr> to
bertrand
parents:
2338
diff
changeset
|
334 // Better test ? |
10622 | 335 if((demux->movi_start < demux->movi_end) && (demux->filepos>=demux->movi_end)){ |
1 | 336 demux->stream->eof=1; |
337 return 0; | |
338 } | |
339 | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
340 stream_read(demux->stream,asf->packet,asf->packetsize); |
1 | 341 if(demux->stream->eof) return 0; // EOF |
25925 | 342 if(asf->packetsize < 2) return 0; // Packet too short |
1 | 343 |
12877
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
344 { |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
345 unsigned char* p=asf->packet; |
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
346 unsigned char* p_end=asf->packet+asf->packetsize; |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
347 unsigned char flags=p[0]; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
348 unsigned char segtype=p[1]; |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
349 unsigned padding; |
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
350 unsigned plen; |
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
351 unsigned sequence; |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
352 unsigned long time=0; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
353 unsigned short duration=0; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
354 |
1 | 355 int segs=1; |
356 unsigned char segsizetype=0x80; | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
357 int seg=-1; |
1 | 358 |
17932 | 359 if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){ |
1 | 360 int i; |
25925 | 361 for(i=0;i<FFMIN(16, asf->packetsize);i++) printf(" %02X",asf->packet[i]); |
1 | 362 printf("\n"); |
363 } | |
364 | |
12877
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
365 // skip ECC data if present by testing bit 7 of flags |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
366 // 1xxxbbbb -> ecc data present, skip bbbb byte(s) |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
367 // 0xxxxxxx -> payload parsing info starts |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
368 if (flags & 0x80) |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
369 { |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
370 p += (flags & 0x0f)+1; |
25925 | 371 if (p+1 >= p_end) return 0; // Packet too short |
12877
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
372 flags = p[0]; |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
373 segtype = p[1]; |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
374 } |
e427e3cc26c1
skip ecc only if present, patch by Alexis Durelle <alexis.durelle@cen.cnamts.fr> (needed for the Aiptek DV3500 camera)
alex
parents:
10832
diff
changeset
|
375 |
1 | 376 //if(segtype!=0x5d) printf("Warning! packet[4] != 0x5d \n"); |
377 | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
378 p+=2; // skip flags & segtype |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
379 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
380 // Read packet size (plen): |
25925 | 381 if(!check_varlen(p, p_end, flags>> 5)) return 0; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
382 plen = read_varlen(&p, flags >> 5, 0); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
383 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
384 // Read sequence: |
25925 | 385 if(!check_varlen(p, p_end, flags>> 1)) return 0; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
386 sequence = read_varlen(&p, flags >> 1, 0); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
387 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
388 // Read padding size (padding): |
25925 | 389 if(!check_varlen(p, p_end, flags>> 3)) return 0; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
390 padding = read_varlen(&p, flags >> 3, 0); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
391 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
392 if(((flags>>5)&3)!=0){ |
1 | 393 // Explicit (absoulte) packet size |
1567 | 394 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Explicit packet size specified: %d \n",plen); |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
395 if(plen>asf->packetsize) mp_msg(MSGT_DEMUX,MSGL_V,"Warning! plen>packetsize! (%d>%d) \n",plen,asf->packetsize); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
396 } else { |
1 | 397 // Padding (relative) size |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
398 plen=asf->packetsize-padding; |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
399 } |
1 | 400 |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
401 // Read time & duration: |
25925 | 402 if (p+5 >= p_end) return 0; // Packet too short |
25488 | 403 time = AV_RL32(p); p+=4; |
404 duration = AV_RL16(p); p+=2; | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
405 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
406 // Read payload flags: |
1 | 407 if(flags&1){ |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
408 // multiple sub-packets |
25925 | 409 if (p >= p_end) return 0; // Packet too short |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
410 segsizetype=p[0]>>6; |
1 | 411 segs=p[0] & 0x3F; |
412 ++p; | |
413 } | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
414 mp_dbg(MSGT_DEMUX,MSGL_DBG4,"%08"PRIu64": flag=%02X segs=%d seq=%u plen=%u pad=%u time=%ld dur=%d\n", |
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
415 (uint64_t)demux->filepos,flags,segs,sequence,plen,padding,time,duration); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
416 |
1 | 417 for(seg=0;seg<segs;seg++){ |
418 //ASF_segmhdr_t* sh; | |
419 unsigned char streamno; | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
420 unsigned int seq; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
421 unsigned int x; // offset or timestamp |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
422 unsigned int rlen; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
423 // |
1 | 424 int len; |
23239 | 425 uint64_t time2=0; |
979 | 426 int keyframe=0; |
1 | 427 |
21968
92f83f7c8eef
Instead of printing a useless "sig11 coming soon" message, just abort parsing
reimar
parents:
20792
diff
changeset
|
428 if(p>=p_end) { |
92f83f7c8eef
Instead of printing a useless "sig11 coming soon" message, just abort parsing
reimar
parents:
20792
diff
changeset
|
429 mp_msg(MSGT_DEMUX,MSGL_V,"Warning! invalid packet 1, aborting parsing...\n"); |
92f83f7c8eef
Instead of printing a useless "sig11 coming soon" message, just abort parsing
reimar
parents:
20792
diff
changeset
|
430 break; |
92f83f7c8eef
Instead of printing a useless "sig11 coming soon" message, just abort parsing
reimar
parents:
20792
diff
changeset
|
431 } |
1 | 432 |
17932 | 433 if( mp_msg_test(MSGT_DEMUX,MSGL_DBG2) ){ |
1 | 434 int i; |
435 printf("seg %d:",seg); | |
25925 | 436 for(i=0;i<FFMIN(16, p_end - p);i++) printf(" %02X",p[i]); |
1 | 437 printf("\n"); |
438 } | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
439 |
1 | 440 streamno=p[0]&0x7F; |
979 | 441 if(p[0]&0x80) keyframe=1; |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
442 p++; |
1 | 443 |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
444 // Read media object number (seq): |
25925 | 445 if(!check_varlen(p, p_end, segtype >> 4)) break; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
446 seq = read_varlen(&p, segtype >> 4, 0); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
447 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
448 // Read offset or timestamp: |
25925 | 449 if(!check_varlen(p, p_end, segtype >> 2)) break; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
450 x = read_varlen(&p, segtype >> 2, 0); |
1 | 451 |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
452 // Read replic.data len: |
25925 | 453 if(!check_varlen(p, p_end, segtype)) break; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
454 rlen = read_varlen(&p, segtype, 0); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
455 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
456 // printf("### rlen=%d \n",rlen); |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
457 |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
458 switch(rlen){ |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
459 case 0x01: // 1 = special, means grouping |
1 | 460 //printf("grouping: %02X \n",p[0]); |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
461 ++p; // skip PTS delta |
1 | 462 break; |
463 default: | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
464 if(rlen>=8){ |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
465 p+=4; // skip object size |
25925 | 466 if (p+3 >= p_end) break; // Packet too short |
25488 | 467 time2=AV_RL32(p); // read PTS |
23239 | 468 if (asf->asf_is_dvr_ms) |
469 get_payload_extension_data(demux, &p, streamno, seq, &keyframe, &time2); | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
470 p+=rlen-4; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
471 } else { |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
472 mp_msg(MSGT_DEMUX,MSGL_V,"unknown segment type (rlen): 0x%02X \n",rlen); |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
6668
diff
changeset
|
473 time2=0; // unknown |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
474 p+=rlen; |
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
475 } |
1 | 476 } |
477 | |
478 if(flags&1){ | |
479 // multiple segments | |
25925 | 480 if(!check_varlen(p, p_end, segsizetype)) break; // Not enough data |
25487
81a77832f5fc
Add a read_varlen function to reduce some code duplication
reimar
parents:
23511
diff
changeset
|
481 len = read_varlen(&p, segsizetype, plen-(p-asf->packet)); |
1 | 482 } else { |
483 // single segment | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
484 len=plen-(p-asf->packet); |
1 | 485 } |
4197 | 486 if(len<0 || (p+len)>p_end){ |
1567 | 487 mp_msg(MSGT_DEMUX,MSGL_V,"ASF_parser: warning! segment len=%d\n",len); |
27267
62b8f385a0b9
Do not just print a warning, also fix the len in ASF demuxer!
reimar
parents:
27122
diff
changeset
|
488 len = p_end - p; |
1 | 489 } |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
490 mp_dbg(MSGT_DEMUX,MSGL_DBG4," seg #%d: streamno=%d seq=%d type=%02X len=%d\n",seg,streamno,seq,rlen,len); |
1 | 491 |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
492 switch(rlen){ |
1 | 493 case 0x01: |
494 // GROUPING: | |
495 //printf("ASF_parser: warning! grouping (flag=1) not yet supported!\n",len); | |
496 //printf(" total: %d \n",len); | |
497 while(len>0){ | |
498 int len2=p[0]; | |
499 p++; | |
500 //printf(" group part: %d bytes\n",len2); | |
27122
f8df4c3e2ac2
Replace asserts by proper conditions to allow playback of some broken but
reimar
parents:
26612
diff
changeset
|
501 if(len2 > len - 1 || len2 < 0) break; // Not enough data |
f8df4c3e2ac2
Replace asserts by proper conditions to allow playback of some broken but
reimar
parents:
26612
diff
changeset
|
502 if(len2 == 0) continue; |
f8df4c3e2ac2
Replace asserts by proper conditions to allow playback of some broken but
reimar
parents:
26612
diff
changeset
|
503 len2 = FFMIN(len2, asf->packetsize); |
979 | 504 demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1,keyframe); |
1 | 505 p+=len2; |
506 len-=len2+1; | |
6668 | 507 ++seq; |
1 | 508 } |
509 if(len!=0){ | |
1567 | 510 mp_msg(MSGT_DEMUX,MSGL_V,"ASF_parser: warning! groups total != len\n"); |
1 | 511 } |
512 break; | |
6442
2eaeb73ce8ab
some cleanup and fixes, but the badquality.asf is still buggy :(
arpi
parents:
4197
diff
changeset
|
513 default: |
1 | 514 // NO GROUPING: |
515 //printf("fragment offset: %d \n",sh->x); | |
27122
f8df4c3e2ac2
Replace asserts by proper conditions to allow playback of some broken but
reimar
parents:
26612
diff
changeset
|
516 if (len <= 0) break; |
26612
87d096a58965
Check ASF packet size before calling demux_asf_read_packet. Fixes segfault
eugeni
parents:
26414
diff
changeset
|
517 if (!asf->asf_is_dvr_ms || asf->found_first_key_frame) { |
27122
f8df4c3e2ac2
Replace asserts by proper conditions to allow playback of some broken but
reimar
parents:
26612
diff
changeset
|
518 len = FFMIN(len, asf->packetsize); |
23239 | 519 demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x,keyframe); |
26612
87d096a58965
Check ASF packet size before calling demux_asf_read_packet. Fixes segfault
eugeni
parents:
26414
diff
changeset
|
520 } |
1 | 521 p+=len; |
522 break; | |
523 } | |
524 | |
525 } // for segs | |
526 return 1; // success | |
527 } | |
528 | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
529 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]); |
1 | 530 return 0; |
531 } | |
1466 | 532 |
533 #include "stheader.h" | |
534 | |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
535 extern void skip_audio_frame(sh_audio_t *sh_audio); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
536 |
17636 | 537 static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
538 struct asf_priv* asf = demuxer->priv; |
1466 | 539 demux_stream_t *d_audio=demuxer->audio; |
540 demux_stream_t *d_video=demuxer->video; | |
541 sh_audio_t *sh_audio=d_audio->sh; | |
542 // sh_video_t *sh_video=d_video->sh; | |
543 | |
544 //FIXME: OFF_T - didn't test ASF case yet (don't have a large asf...) | |
545 //FIXME: reports good or bad to steve@daviesfam.org please | |
546 | |
547 //================= seek in ASF ========================== | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
548 float p_rate=asf->packetrate; // packets / sec |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
549 off_t rel_seek_packs=(flags&SEEK_FACTOR)? // FIXME: int may be enough? |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
550 (rel_seek_secs*(demuxer->movi_end-demuxer->movi_start)/asf->packetsize): |
1628
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1567
diff
changeset
|
551 (rel_seek_secs*p_rate); |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
552 off_t rel_seek_bytes=rel_seek_packs*asf->packetsize; |
1466 | 553 off_t newpos; |
554 //printf("ASF: packs: %d duration: %d \n",(int)fileh.packets,*((int*)&fileh.duration)); | |
555 // printf("ASF_seek: %d secs -> %d packs -> %d bytes \n", | |
556 // rel_seek_secs,rel_seek_packs,rel_seek_bytes); | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
557 newpos=((flags&SEEK_ABSOLUTE)?demuxer->movi_start:demuxer->filepos)+rel_seek_bytes; |
1466 | 558 if(newpos<0 || newpos<demuxer->movi_start) newpos=demuxer->movi_start; |
559 // printf("\r -- asf: newpos=%d -- \n",newpos); | |
560 stream_seek(demuxer->stream,newpos); | |
561 | |
19961
9f011e6892e8
interpolate real fps of dvr-ms files using the extended stream properties.
nicodvb
parents:
18710
diff
changeset
|
562 if (asf->asf_is_dvr_ms) asf->dvr_last_vid_pts = 0.0f; |
9f011e6892e8
interpolate real fps of dvr-ms files using the extended stream properties.
nicodvb
parents:
18710
diff
changeset
|
563 |
13310
c629f7ac9b9f
fix seeking in audio-only case (crash when seeking backwards, time reset to 0)
reimar
parents:
12877
diff
changeset
|
564 if (d_video->id >= 0) |
1466 | 565 ds_fill_buffer(d_video); |
566 if(sh_audio){ | |
567 ds_fill_buffer(d_audio); | |
568 } | |
569 | |
18710
c528c6c518f1
Clean up audio pts handling, make audio pts tracking in the audio-only
uau
parents:
18609
diff
changeset
|
570 if (d_video->id >= 0) |
1466 | 571 while(1){ |
572 if(sh_audio && !d_audio->eof){ | |
573 float a_pts=d_audio->pts; | |
574 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; | |
575 // sync audio: | |
576 if (d_video->pts > a_pts){ | |
577 skip_audio_frame(sh_audio); | |
578 // if(!ds_fill_buffer(d_audio)) sh_audio=NULL; // skip audio. EOF? | |
579 continue; | |
580 } | |
581 } | |
582 if(d_video->flags&1) break; // found a keyframe! | |
583 if(!ds_fill_buffer(d_video)) break; // skip frame. EOF? | |
584 } | |
585 | |
586 | |
587 } | |
588 | |
16175 | 589 static int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){ |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
590 struct asf_priv* asf = demuxer->priv; |
8254
772d6d27fd66
warning patch by (Dominik Mierzejewski <dominik at rangers dot eu dot org>)
michael
parents:
8208
diff
changeset
|
591 /* demux_stream_t *d_audio=demuxer->audio; |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
592 demux_stream_t *d_video=demuxer->video; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
593 sh_audio_t *sh_audio=d_audio->sh; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
594 sh_video_t *sh_video=d_video->sh; |
8254
772d6d27fd66
warning patch by (Dominik Mierzejewski <dominik at rangers dot eu dot org>)
michael
parents:
8208
diff
changeset
|
595 */ |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
596 switch(cmd) { |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
597 case DEMUXER_CTRL_GET_TIME_LENGTH: |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
598 *((double *)arg)=(double)(asf->movielength); |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
599 return DEMUXER_CTRL_OK; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
600 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
601 case DEMUXER_CTRL_GET_PERCENT_POS: |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
602 return DEMUXER_CTRL_DONTKNOW; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
603 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
604 default: |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
605 return DEMUXER_CTRL_NOTIMPL; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
606 } |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
607 } |
16175 | 608 |
609 | |
610 static demuxer_t* demux_open_asf(demuxer_t* demuxer) | |
611 { | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
612 struct asf_priv* asf = demuxer->priv; |
16175 | 613 sh_audio_t *sh_audio=NULL; |
614 sh_video_t *sh_video=NULL; | |
615 | |
616 //---- ASF header: | |
17992
2545bbd91450
Move global vars used for header parsing, etc to dewux->priv as it should
albeu
parents:
17932
diff
changeset
|
617 if(!asf) return NULL; |
23239 | 618 init_priv(asf); |
23295 | 619 if (!read_asf_header(demuxer,asf)) |
17598
4b8193d51bda
we cannot continue without a crash when read_asf_header fails, since some
reimar
parents:
17569
diff
changeset
|
620 return NULL; |
16175 | 621 stream_reset(demuxer->stream); |
622 stream_seek(demuxer->stream,demuxer->movi_start); | |
623 // demuxer->idx_pos=0; | |
624 // demuxer->endpos=avi_header.movi_end; | |
625 if(demuxer->video->id != -2) { | |
626 if(!ds_fill_buffer(demuxer->video)){ | |
627 mp_msg(MSGT_DEMUXER,MSGL_WARN,"ASF: " MSGTR_MissingVideoStream); | |
628 demuxer->video->sh=NULL; | |
629 //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n"); | |
630 } else { | |
631 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video; | |
23239 | 632 sh_video->fps=1000.0f; sh_video->frametime=0.001f; |
20636
325db3f2aba3
don't set the resolution for dvr-ms files: in the asf headers it seems to
nicodvb
parents:
19961
diff
changeset
|
633 |
325db3f2aba3
don't set the resolution for dvr-ms files: in the asf headers it seems to
nicodvb
parents:
19961
diff
changeset
|
634 if (asf->asf_is_dvr_ms) { |
325db3f2aba3
don't set the resolution for dvr-ms files: in the asf headers it seems to
nicodvb
parents:
19961
diff
changeset
|
635 sh_video->bih->biWidth = 0; |
325db3f2aba3
don't set the resolution for dvr-ms files: in the asf headers it seems to
nicodvb
parents:
19961
diff
changeset
|
636 sh_video->bih->biHeight = 0; |
325db3f2aba3
don't set the resolution for dvr-ms files: in the asf headers it seems to
nicodvb
parents:
19961
diff
changeset
|
637 } |
16175 | 638 } |
639 } | |
640 | |
641 if(demuxer->audio->id!=-2){ | |
642 mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_ASFSearchingForAudioStream,demuxer->audio->id); | |
643 if(!ds_fill_buffer(demuxer->audio)){ | |
644 mp_msg(MSGT_DEMUXER,MSGL_INFO,"ASF: " MSGTR_MissingAudioStream); | |
645 demuxer->audio->sh=NULL; | |
646 } else { | |
647 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio; | |
648 sh_audio->format=sh_audio->wf->wFormatTag; | |
649 } | |
650 } | |
20792
dcaf8b9f47e9
Fix crash when attempting to seek in a streamed unseekable stream, like
gpoirier
parents:
20636
diff
changeset
|
651 if(!demuxer->stream->seek) |
dcaf8b9f47e9
Fix crash when attempting to seek in a streamed unseekable stream, like
gpoirier
parents:
20636
diff
changeset
|
652 demuxer->seekable=0; |
16175 | 653 |
654 return demuxer; | |
655 } | |
656 | |
657 | |
23239 | 658 static void demux_close_asf(demuxer_t *demuxer) { |
659 struct asf_priv* asf = demuxer->priv; | |
660 | |
661 if (!asf) return; | |
662 | |
663 if (asf->aud_repdata_sizes) | |
664 free(asf->aud_repdata_sizes); | |
665 | |
666 if (asf->vid_repdata_sizes) | |
667 free(asf->vid_repdata_sizes); | |
668 | |
669 free(asf); | |
670 } | |
671 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25488
diff
changeset
|
672 const demuxer_desc_t demuxer_desc_asf = { |
16175 | 673 "ASF demuxer", |
17232
d318e2ff799e
Typo in ASF demuxer selection by name (it's 'asf', not 'asv')
rtognimp
parents:
17226
diff
changeset
|
674 "asf", |
16175 | 675 "ASF", |
676 "A'rpi", | |
677 "ASF, WMV, WMA", | |
678 DEMUXER_TYPE_ASF, | |
679 1, // safe autodetect | |
680 asf_check_header, | |
681 demux_asf_fill_buffer, | |
682 demux_open_asf, | |
23239 | 683 demux_close_asf, |
16175 | 684 demux_seek_asf, |
685 demux_asf_control | |
686 }; |