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