Mercurial > mplayer.hg
annotate libmpdemux/demux_nemesi.c @ 34346:3d0c795524b0
Fix bug with wrong focus in file selector.
The focus can only be set to fsFNameList after it's realized and mapped.
This also removes the irritating selection of the fsPathCombo.
author | ib |
---|---|
date | Sun, 11 Dec 2011 16:02:02 +0000 |
parents | a93891202051 |
children | dba1b5aa72c1 |
rev | line source |
---|---|
24564 | 1 /* |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
2 * Copyright (C) 2007 Alessandro Molina <amol.wrk@gmail.com> |
24564 | 3 * |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
4 * This file is part of MPlayer. |
24564 | 5 * |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
6 * MPlayer is free software; you can redistribute it and/or modify |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
7 * it under the terms of the GNU General Public License as published by |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
8 * the Free Software Foundation; either version 2 of the License, or |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
9 * (at your option) any later version. |
24564 | 10 * |
26742
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
11 * MPlayer is distributed in the hope that it will be useful, |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
14 * GNU General Public License for more details. |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
15 * |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
16 * You should have received a copy of the GNU General Public License along |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
0c1db5fd3f79
Use standard license headers with standard formatting.
diego
parents:
25965
diff
changeset
|
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
24564 | 19 */ |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33858
diff
changeset
|
20 |
25267 | 21 #include <stdlib.h> |
22 #include <stdio.h> | |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33858
diff
changeset
|
23 |
25267 | 24 #include "stream/stream.h" |
32059
319657dba8e1
Replace force_fps extern declaration by mpcommon.h #include.
diego
parents:
31609
diff
changeset
|
25 #include "mpcommon.h" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33858
diff
changeset
|
26 #include "mp_msg.h" |
25267 | 27 #include "demuxer.h" |
24564 | 28 #include "stheader.h" |
29 #include "nemesi/rtsp.h" | |
30 #include "nemesi/rtp.h" | |
24856 | 31 #include <sched.h> |
24564 | 32 |
31282 | 33 int rtsp_transport_http = 0; |
24564 | 34 int rtsp_transport_tcp = 0; |
35 int rtsp_transport_sctp = 0; | |
25156 | 36 int rtsp_port = 0; |
24564 | 37 |
25103 | 38 typedef struct { |
39 char * mime; | |
40 unsigned int fourcc; | |
41 } MIMEto4CC; | |
42 | |
43 #define NMS_MAX_FORMATS 16 | |
44 | |
45 MIMEto4CC supported_audio[NMS_MAX_FORMATS] = { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27023
diff
changeset
|
46 {"MPA", 0x55}, |
25103 | 47 {"vorbis", mmioFOURCC('v','r','b','s')}, |
25104 | 48 {"mpeg4-generic", mmioFOURCC('M','P','4','A')}, |
25103 | 49 {NULL, 0}, |
50 }; | |
51 | |
52 MIMEto4CC supported_video[NMS_MAX_FORMATS] = { | |
53 {"MPV", mmioFOURCC('M','P','E','G')}, | |
25116 | 54 {"theora",mmioFOURCC('t','h','e','o')}, |
25103 | 55 {"H264", mmioFOURCC('H','2','6','4')}, |
56 {"H263-1998", mmioFOURCC('H','2','6','3')}, | |
57 {"MP4V-ES", mmioFOURCC('M','P','4','V')}, | |
58 {NULL, 0}, | |
59 }; | |
60 | |
24564 | 61 typedef enum { NEMESI_SESSION_VIDEO, |
62 NEMESI_SESSION_AUDIO } Nemesi_SessionType; | |
63 | |
64 typedef struct { | |
65 rtsp_ctrl * rtsp; | |
66 rtp_session * session[2]; | |
67 rtp_frame first_pkt[2]; | |
68 double time[2]; | |
69 double seek; | |
70 } Nemesi_DemuxerStreamData; | |
71 | |
24997 | 72 |
73 #define STYPE_TO_DS(demuxer, stype) \ | |
74 ((stype) == NEMESI_SESSION_VIDEO ? (demuxer)->video : (demuxer)->audio) | |
75 | |
76 #define DS_TO_STYPE(demuxer, ds) \ | |
77 ((ds) == (demuxer)->video ? NEMESI_SESSION_VIDEO : NEMESI_SESSION_AUDIO) | |
78 | |
79 #define INVERT_STYPE(stype) ((stype + 1) % 2) | |
80 | |
25103 | 81 static unsigned int get4CC(MIMEto4CC * supported_formats, char const * format) |
82 { | |
83 unsigned i; | |
84 | |
85 for(i = 0; i < NMS_MAX_FORMATS; ++i) { | |
86 if (!supported_formats[i].mime) | |
87 return 0; | |
88 else if ( strcmp(supported_formats[i].mime, format) == 0 ) | |
89 return supported_formats[i].fourcc; | |
90 } | |
91 | |
92 return 0; | |
93 } | |
24997 | 94 |
95 static rtp_ssrc *wait_for_packets(Nemesi_DemuxerStreamData * ndsd, Nemesi_SessionType stype) | |
96 { | |
97 rtp_ssrc *ssrc = NULL; | |
98 | |
99 /* Wait for prebuffering (prebuffering must be enabled in nemesi) */ | |
100 int terminated = rtp_fill_buffers(rtsp_get_rtp_th(ndsd->rtsp)); | |
101 | |
102 /* Wait for the ssrc to be registered, if prebuffering is on in nemesi | |
103 this will just get immediatly the correct ssrc */ | |
104 if (!terminated) { | |
105 while ( !(ssrc = rtp_session_get_ssrc(ndsd->session[stype], ndsd->rtsp)) ) | |
106 sched_yield(); | |
107 } | |
108 | |
109 return ssrc; | |
110 } | |
111 | |
24564 | 112 static void link_session_and_fetch_conf(Nemesi_DemuxerStreamData * ndsd, |
113 Nemesi_SessionType stype, | |
114 rtp_session * sess, | |
115 rtp_buff * buff, unsigned int * fps) | |
116 { | |
24855
2c790baff42c
Update to use newer libnemesi, should fix desync, fps guessing may fail now
lu_zero
parents:
24625
diff
changeset
|
117 rtp_ssrc *ssrc = NULL; |
24564 | 118 rtp_frame * fr = &ndsd->first_pkt[stype]; |
119 rtp_buff trash_buff; | |
25010 | 120 int must_prefetch = ((fps != NULL) || (buff != NULL)) ? 1 : 0; |
24564 | 121 |
122 ndsd->session[stype] = sess; | |
123 | |
24997 | 124 ssrc = wait_for_packets(ndsd, stype); |
24564 | 125 |
25010 | 126 if ( ((ssrc) && (must_prefetch)) ) { |
24997 | 127 if (buff == NULL) |
128 buff = &trash_buff; | |
24856 | 129 |
130 rtp_fill_buffer(ssrc, fr, buff); //Prefetch the first packet | |
24564 | 131 |
24998 | 132 /* Packet prefecthing must be done anyway or we won't be |
133 able to get the metadata, but fps calculation happens | |
134 only if the user didn't specify the FPS */ | |
25010 | 135 if ( ((!force_fps) && (fps != NULL)) ) { |
24998 | 136 while ( *fps <= 0 ) { |
137 //Wait more pkts to calculate FPS and try again | |
138 sched_yield(); | |
139 *fps = rtp_get_fps(ssrc); | |
140 } | |
141 } | |
24564 | 142 } |
143 } | |
144 | |
25267 | 145 static demuxer_t* demux_open_rtp(demuxer_t* demuxer) |
24564 | 146 { |
147 nms_rtsp_hints hints; | |
148 char * url = demuxer->stream->streaming_ctrl->url->url; | |
149 rtsp_ctrl * ctl; | |
150 RTSP_Error reply; | |
151 rtsp_medium * media; | |
152 Nemesi_DemuxerStreamData * ndsd = calloc(1, sizeof(Nemesi_DemuxerStreamData)); | |
153 | |
154 memset(&hints,0,sizeof(hints)); | |
25156 | 155 if (rtsp_port) hints.first_rtp_port = rtsp_port; |
24564 | 156 if (rtsp_transport_tcp) { |
157 hints.pref_rtsp_proto = TCP; | |
158 hints.pref_rtp_proto = TCP; | |
159 } | |
160 if (rtsp_transport_sctp) { | |
161 hints.pref_rtsp_proto = SCTP; | |
162 hints.pref_rtp_proto = SCTP; | |
163 } | |
164 | |
165 mp_msg(MSGT_DEMUX, MSGL_INFO, "Initializing libNemesi\n"); | |
166 if ((ctl = rtsp_init(&hints)) == NULL) { | |
167 free(ndsd); | |
168 return STREAM_ERROR; | |
169 } | |
170 | |
171 ndsd->rtsp = ctl; | |
172 demuxer->priv = ndsd; | |
173 //nms_verbosity_set(1); | |
174 | |
175 mp_msg(MSGT_DEMUX, MSGL_INFO, "Opening: %s\n", url); | |
176 if (rtsp_open(ctl, url)) { | |
177 mp_msg(MSGT_DEMUX, MSGL_ERR, "rtsp_open failed.\n"); | |
178 return demuxer; | |
179 } | |
180 | |
181 reply = rtsp_wait(ctl); | |
182 if (reply.got_error) { | |
183 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
184 "OPEN Error from the server: %s\n", | |
185 reply.message.reply_str); | |
186 return demuxer; | |
187 } | |
188 | |
189 rtsp_play(ctl, 0, 0); | |
190 reply = rtsp_wait(ctl); | |
191 if (reply.got_error) { | |
192 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
193 "PLAY Error from the server: %s\n", | |
194 reply.message.reply_str); | |
195 return demuxer; | |
196 } | |
197 | |
25490 | 198 if (!ctl->rtsp_queue) |
199 return demuxer; | |
200 | |
24564 | 201 media = ctl->rtsp_queue->media_queue; |
202 for (; media; media=media->next) { | |
203 sdp_medium_info * info = media->medium_info; | |
204 rtp_session * sess = media->rtp_sess; | |
25011 | 205 rtp_buff buff; |
24564 | 206 |
207 int media_format = atoi(info->fmts); | |
208 rtp_pt * ptinfo = rtp_get_pt_info(sess, media_format); | |
209 char const * format_name = ptinfo ? ptinfo->name : NULL; | |
210 | |
25011 | 211 memset(&buff, 0, sizeof(rtp_buff)); |
212 | |
24564 | 213 if (sess->parsers[media_format] == NULL) { |
214 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
215 "libNemesi unsupported media format: %s\n", | |
216 format_name ? format_name : info->fmts); | |
217 continue; | |
218 } | |
219 else { | |
220 mp_msg(MSGT_DEMUX, MSGL_INFO, | |
221 "libNemesi supported media: %s\n", | |
222 format_name); | |
223 } | |
224 | |
225 if (ptinfo->type == AU) { | |
226 if (ndsd->session[NEMESI_SESSION_AUDIO] == NULL) { | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31282
diff
changeset
|
227 sh_audio_t* sh_audio = new_sh_audio(demuxer,0, NULL); |
25011 | 228 WAVEFORMATEX* wf; |
24564 | 229 demux_stream_t* d_audio = demuxer->audio; |
27023 | 230 demuxer->audio->id = 0; |
24564 | 231 |
232 mp_msg(MSGT_DEMUX, MSGL_INFO, "Detected as AUDIO stream...\n"); | |
233 | |
234 link_session_and_fetch_conf(ndsd, NEMESI_SESSION_AUDIO, | |
25011 | 235 sess, &buff, NULL); |
236 | |
32125 | 237 wf = calloc(1,sizeof(*wf)+buff.len); |
238 wf->cbSize = buff.len; | |
239 memcpy(wf+1, buff.data, buff.len); | |
24564 | 240 |
241 sh_audio->wf = wf; | |
242 d_audio->sh = sh_audio; | |
243 sh_audio->ds = d_audio; | |
244 wf->nSamplesPerSec = 0; | |
245 | |
25103 | 246 wf->wFormatTag = |
247 sh_audio->format = get4CC(supported_audio, format_name); | |
248 if ( !(wf->wFormatTag) ) | |
24564 | 249 mp_msg(MSGT_DEMUX, MSGL_WARN, |
250 "Unknown MPlayer format code for MIME" | |
251 " type \"audio/%s\"\n", format_name); | |
252 } else { | |
253 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
254 "There is already an audio session registered," | |
255 " ignoring...\n"); | |
256 } | |
257 } else if (ptinfo->type == VI) { | |
25012 | 258 if (ndsd->session[NEMESI_SESSION_VIDEO] == NULL) { |
24564 | 259 sh_video_t* sh_video; |
260 BITMAPINFOHEADER* bih; | |
261 demux_stream_t* d_video; | |
262 int fps = 0; | |
263 | |
264 mp_msg(MSGT_DEMUX, MSGL_INFO, "Detected as VIDEO stream...\n"); | |
265 | |
266 link_session_and_fetch_conf(ndsd, NEMESI_SESSION_VIDEO, | |
267 sess, &buff, &fps); | |
268 | |
32125 | 269 bih = calloc(1,sizeof(*bih)+buff.len); |
270 bih->biSize = sizeof(*bih)+buff.len; | |
271 memcpy(bih+1, buff.data, buff.len); | |
24564 | 272 |
273 sh_video = new_sh_video(demuxer,0); | |
274 sh_video->bih = bih; | |
275 d_video = demuxer->video; | |
276 d_video->sh = sh_video; | |
277 sh_video->ds = d_video; | |
278 | |
24856 | 279 if (fps) { |
24564 | 280 sh_video->fps = fps; |
24856 | 281 sh_video->frametime = 1.0/fps; |
282 } | |
24564 | 283 |
25103 | 284 bih->biCompression = |
285 sh_video->format = get4CC(supported_video, format_name); | |
286 if ( !(bih->biCompression) ) { | |
24564 | 287 mp_msg(MSGT_DEMUX, MSGL_WARN, |
288 "Unknown MPlayer format code for MIME" | |
289 " type \"video/%s\"\n", format_name); | |
290 } | |
291 } else { | |
292 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
293 "There is already a video session registered," | |
294 " ignoring...\n"); | |
295 } | |
296 } else { | |
297 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported media type\n"); | |
298 } | |
299 } | |
300 | |
301 demuxer->stream->eof = 0; | |
302 | |
303 return demuxer; | |
304 } | |
305 | |
306 static int get_data_for_session(Nemesi_DemuxerStreamData * ndsd, | |
24997 | 307 Nemesi_SessionType stype, rtp_ssrc * ssrc, |
308 rtp_frame * fr) | |
24564 | 309 { |
24997 | 310 if (ndsd->first_pkt[stype].len != 0) { |
311 fr->data = ndsd->first_pkt[stype].data; | |
312 fr->time_sec = ndsd->first_pkt[stype].time_sec; | |
313 fr->len = ndsd->first_pkt[stype].len; | |
314 ndsd->first_pkt[stype].len = 0; | |
315 return RTP_FILL_OK; | |
316 } else { | |
317 rtp_buff buff; | |
318 return rtp_fill_buffer(ssrc, fr, &buff); | |
319 } | |
320 } | |
24564 | 321 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27023
diff
changeset
|
322 static void stream_add_packet(Nemesi_DemuxerStreamData * ndsd, |
24997 | 323 Nemesi_SessionType stype, |
324 demux_stream_t* ds, rtp_frame * fr) | |
325 { | |
326 demux_packet_t* dp = new_demux_packet(fr->len); | |
327 memcpy(dp->buffer, fr->data, fr->len); | |
24564 | 328 |
24997 | 329 fr->time_sec += ndsd->seek; |
330 ndsd->time[stype] = dp->pts = fr->time_sec; | |
331 | |
332 ds_add_packet(ds, dp); | |
24564 | 333 } |
334 | |
25267 | 335 static int demux_rtp_fill_buffer(demuxer_t* demuxer, demux_stream_t* ds) |
24564 | 336 { |
337 Nemesi_DemuxerStreamData * ndsd = demuxer->priv; | |
338 Nemesi_SessionType stype; | |
24997 | 339 rtp_ssrc * ssrc; |
24564 | 340 rtp_frame fr; |
341 | |
24997 | 342 if ( (!ndsd->rtsp->rtsp_queue) || (demuxer->stream->eof) ) { |
24564 | 343 mp_msg(MSGT_DEMUX, MSGL_INFO, "End of Stream...\n"); |
344 demuxer->stream->eof = 1; | |
345 return 0; | |
346 } | |
347 | |
25103 | 348 memset(&fr, 0, sizeof(fr)); |
349 | |
24997 | 350 stype = DS_TO_STYPE(demuxer, ds); |
351 if ( (ssrc = wait_for_packets(ndsd, stype)) == NULL ) { | |
352 mp_msg(MSGT_DEMUX, MSGL_INFO, "Bye...\n"); | |
353 demuxer->stream->eof = 1; | |
24564 | 354 return 0; |
355 } | |
356 | |
24997 | 357 if(!get_data_for_session(ndsd, stype, ssrc, &fr)) |
358 stream_add_packet(ndsd, stype, ds, &fr); | |
359 else { | |
360 stype = INVERT_STYPE(stype); | |
25013
dc6b7ad240db
Check for second stream presence, fixes single stream playback (from amol)
lu_zero
parents:
25012
diff
changeset
|
361 |
dc6b7ad240db
Check for second stream presence, fixes single stream playback (from amol)
lu_zero
parents:
25012
diff
changeset
|
362 //Must check if we actually have a stream of the other type |
dc6b7ad240db
Check for second stream presence, fixes single stream playback (from amol)
lu_zero
parents:
25012
diff
changeset
|
363 if (!ndsd->session[stype]) |
dc6b7ad240db
Check for second stream presence, fixes single stream playback (from amol)
lu_zero
parents:
25012
diff
changeset
|
364 return 1; |
dc6b7ad240db
Check for second stream presence, fixes single stream playback (from amol)
lu_zero
parents:
25012
diff
changeset
|
365 |
24997 | 366 ds = STYPE_TO_DS(demuxer, stype); |
367 ssrc = wait_for_packets(ndsd, stype); | |
368 | |
369 if(!get_data_for_session(ndsd, stype, ssrc, &fr)) | |
370 stream_add_packet(ndsd, stype, ds, &fr); | |
24564 | 371 } |
372 | |
373 return 1; | |
374 } | |
375 | |
376 | |
25267 | 377 static void demux_close_rtp(demuxer_t* demuxer) |
24564 | 378 { |
379 Nemesi_DemuxerStreamData * ndsd = demuxer->priv; | |
380 rtsp_ctrl * ctl = ndsd->rtsp; | |
381 RTSP_Error err; | |
382 | |
383 mp_msg(MSGT_DEMUX, MSGL_INFO, "Closing libNemesi RTSP Stream...\n"); | |
384 | |
385 if (ndsd == NULL) | |
386 return; | |
387 | |
388 free(ndsd); | |
389 | |
390 if (rtsp_close(ctl)) { | |
391 err = rtsp_wait(ctl); | |
392 if (err.got_error) | |
393 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
394 "Error Closing Stream: %s\n", | |
395 err.message.reply_str); | |
396 } | |
397 | |
398 rtsp_uninit(ctl); | |
399 } | |
400 | |
401 static void demux_seek_rtp(demuxer_t *demuxer, float rel_seek_secs, | |
402 float audio_delay, int flags) | |
403 { | |
404 Nemesi_DemuxerStreamData * ndsd = demuxer->priv; | |
405 rtsp_ctrl * ctl = ndsd->rtsp; | |
406 sdp_attr * r_attr = NULL; | |
407 sdp_range r = {0, 0}; | |
408 double time = ndsd->time[NEMESI_SESSION_VIDEO] ? | |
409 ndsd->time[NEMESI_SESSION_VIDEO] : | |
410 ndsd->time[NEMESI_SESSION_AUDIO]; | |
411 | |
412 if (!ctl->rtsp_queue) | |
413 return; | |
414 | |
415 r_attr = sdp_get_attr(ctl->rtsp_queue->info->attr_list, "range"); | |
416 if (r_attr) | |
417 r = sdp_parse_range(r_attr->value); | |
418 | |
419 //flags & 1 -> absolute seek | |
420 //flags & 2 -> percent seek | |
421 if (flags == 0) { | |
422 time += rel_seek_secs; | |
423 if (time < r.begin) | |
424 time = r.begin; | |
425 else if (time > r.end) | |
426 time = r.end; | |
427 ndsd->seek = time; | |
428 | |
429 mp_msg(MSGT_DEMUX,MSGL_WARN,"libNemesi SEEK %f on %f - %f)\n", | |
430 time, r.begin, r.end); | |
431 | |
432 if (!rtsp_seek(ctl, time, 0)) { | |
433 RTSP_Error err = rtsp_wait(ctl); | |
434 if (err.got_error) { | |
435 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
436 "Error Performing Seek: %s\n", | |
437 err.message.reply_str); | |
438 demuxer->stream->eof = 1; | |
439 } | |
440 else | |
441 mp_msg(MSGT_DEMUX, MSGL_INFO, "Seek, performed\n"); | |
442 } | |
443 else { | |
444 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unable to pause stream to perform seek\n"); | |
445 demuxer->stream->eof = 1; | |
446 } | |
447 } | |
448 else | |
449 mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported seek type\n"); | |
450 } | |
451 | |
30644
390c8d36d463
Drop weird and unnecessary _s/_st suffixes from demuxer struct names.
diego
parents:
29263
diff
changeset
|
452 static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg) |
24564 | 453 { |
454 Nemesi_DemuxerStreamData * ndsd = demuxer->priv; | |
455 rtsp_ctrl * ctl = ndsd->rtsp; | |
456 sdp_attr * r_attr = NULL; | |
457 sdp_range r = {0, 0}; | |
458 double time = ndsd->time[NEMESI_SESSION_VIDEO] ? | |
459 ndsd->time[NEMESI_SESSION_VIDEO] : | |
460 ndsd->time[NEMESI_SESSION_AUDIO]; | |
461 | |
462 if (!ctl->rtsp_queue) | |
463 return DEMUXER_CTRL_DONTKNOW; | |
464 | |
465 r_attr = sdp_get_attr(ctl->rtsp_queue->info->attr_list, "range"); | |
466 if (r_attr) | |
467 r = sdp_parse_range(r_attr->value); | |
468 | |
469 switch (cmd) { | |
470 case DEMUXER_CTRL_GET_TIME_LENGTH: | |
471 if (r.end == 0) | |
472 return DEMUXER_CTRL_DONTKNOW; | |
473 | |
474 *((double *)arg) = ((double)r.end) - ((double)r.begin); | |
475 return DEMUXER_CTRL_OK; | |
476 | |
477 case DEMUXER_CTRL_GET_PERCENT_POS: | |
478 if (r.end == 0) | |
479 return DEMUXER_CTRL_DONTKNOW; | |
480 | |
481 *((int *)arg) = (int)( time * 100 / (r.end - r.begin) ); | |
482 return DEMUXER_CTRL_OK; | |
483 default: | |
484 return DEMUXER_CTRL_DONTKNOW; | |
485 } | |
486 } | |
487 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25490
diff
changeset
|
488 const demuxer_desc_t demuxer_desc_rtp_nemesi = { |
25270 | 489 "libnemesi RTP demuxer", |
490 "nemesi", | |
24564 | 491 "", |
492 "Alessandro Molina", | |
25270 | 493 "requires libnemesi", |
25266
239330301b33
Make libnemesi use specific struct and DEMUXER_TYPE
lu_zero
parents:
25156
diff
changeset
|
494 DEMUXER_TYPE_RTP_NEMESI, |
24564 | 495 0, // no autodetect |
496 NULL, | |
497 demux_rtp_fill_buffer, | |
498 demux_open_rtp, | |
499 demux_close_rtp, | |
500 demux_seek_rtp, | |
501 demux_rtp_control | |
502 }; |