summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xine_input_vdr.c86
1 files changed, 54 insertions, 32 deletions
diff --git a/xine_input_vdr.c b/xine_input_vdr.c
index 1b03eb68..a5370060 100644
--- a/xine_input_vdr.c
+++ b/xine_input_vdr.c
@@ -4,7 +4,7 @@
* See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
- * $Id: xine_input_vdr.c,v 1.19 2006-07-23 21:35:54 phintuka Exp $
+ * $Id: xine_input_vdr.c,v 1.20 2006-07-24 01:05:25 phintuka Exp $
*
*/
@@ -3346,27 +3346,46 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
pkt->pos = ntohull(pkt->pos);
/* Check for control messages */
- if(pkt->seq == (uint16_t)(-1) /*0xffff*/) {
- if(pkt->pos == (uint64_t)(-1ULL) /*0xffffffff*/) {
- if(pkt_data[0]) { /* -> can't be PES frame */
- pkt_data[64] = 0;
- if(!strncmp((char*)pkt_data, "UDP MISSING", 11)) {
- /* Re-send failed */
- int seq1 = 0, seq2 = 0;
- uint64_t rpos = 0ULL;
- sscanf((char*)pkt_data, "UDP MISSING %d-%d %" PRIu64,
- &seq1, &seq2, &rpos);
- read_buffer->size = sizeof(stream_udp_header_t);
- read_buffer->type = BUF_MAJOR_MASK;
- pkt->seq = seq1;
- pkt->pos = rpos;
- udp->missed_frames++;
- /* -> drop frame thru as empty ; it will trigger queue to continue */
- } else {
- vdr_plugin_parse_control((input_plugin_t*)this, (char*)pkt_data);
- }
+ if(pkt->seq == (uint16_t)(-1) /*0xffff*/ &&
+ pkt->pos == (uint64_t)(-1ULL) /*0xffffffff*/ &&
+ pkt_data[0]) { /* -> can't be PES frame */
+ pkt_data[64] = 0;
+ if(!strncmp((char*)pkt_data, "UDP MISSING", 11)) {
+ /* Re-send failed */
+ int seq1 = 0, seq2 = 0;
+ uint64_t rpos = 0ULL;
+ sscanf((char*)pkt_data, "UDP MISSING %d-%d %" PRIu64,
+ &seq1, &seq2, &rpos);
+ read_buffer->size = sizeof(stream_udp_header_t);
+ read_buffer->type = BUF_MAJOR_MASK;
+ pkt->pos = rpos;
+ LOGUDP("Got UDP MISSING %d-%d (currseq=%d)", seq1, seq2, udp->next_seq);
+ if(seq1 == udp->next_seq) {
+ /* this is the one we are expecting ... */
+ int n = ADDSEQ(seq2 + 1, -seq1);
+ ADDSEQ(udp->next_seq, n);
+ udp->missed_frames += n;
+ seq2 &= UDP_SEQ_MASK;
+ pkt->seq = seq2;
+ udp->next_seq = seq2;
+ LOGDP(" accepted: now currseq %d", udp->next_seq);
+ /* -> drop frame thru as empty ; it will trigger queue to continue */
+ } else {
+ LOGUDP(" rejected: not expected seq ???");
continue;
- } /* if(pkt_data[0] */
+ }
+ } else {
+ LOGMSG("Control message in data stream: %s", (char*)pkt_data);
+ vdr_plugin_parse_control((input_plugin_t*)this, (char*)pkt_data);
+ /* #warning some messages should be delayed and executed in read_block
+ (ex. audio/spu stream changes, flush) */
+ continue;
+ }
+ } else {
+ /* Check for PES header */
+ if(pkt_data[0] || pkt_data[1] || pkt_data[2] != 1) {
+ LOGMSG("received invalid UDP packet (PES header 0x000001 missing)");
+ continue;
}
}
@@ -3375,11 +3394,6 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
LOGMSG("received invalid UDP packet (sequence number too big)");
continue;
}
- if(pkt_data[0] || pkt_data[1] || pkt_data[2] != 1) {
- LOGMSG("received invalid UDP packet (PES header 0x000001 missing)");
- continue;
- }
-
/*
* handle re-ordering and retransmissios
@@ -3394,13 +3408,13 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
/* check if received sequence number is inside allowed window
(half of whole range) */
- /*if(((current_seq + (UDP_SEQ_MASK+1) - udp->next_seq) & UDP_SEQ_MASK) > */
if(ADDSEQ(current_seq, -udp->next_seq) > ((UDP_SEQ_MASK+1) >> 1)/*0x80*/) {
struct sockaddr_in sin;
LOGUDP("Received SeqNo out of window (%d ; [%d..%d])",
current_seq, udp->next_seq,
(udp->next_seq+((UDP_SEQ_MASK+1) >> 1)/*0x80*/) & UDP_SEQ_MASK);
/* reset link */
+ LOGDBG("UDP: resetting link");
memcpy(&sin, &udp->server_address, sizeof(sin));
free_udp_data(udp);
udp = this->udp_data = init_udp_data();
@@ -3424,7 +3438,6 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
read_buffer = NULL;
udp->queued ++;
-
/* stay inside receiving window:
If window exceeded, skip missing frames */
if(udp->queued > ((UDP_SEQ_MASK+1)>>2)) {
@@ -3442,14 +3455,17 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
/* flush continous part of queue to demuxer queue */
while(udp->queued > 0 && udp->queue[udp->next_seq]) {
- this->block_buffer->put(this->block_buffer, udp->queue[udp->next_seq]);
pkt = (stream_udp_header_t*)udp->queue[udp->next_seq]->content;
udp->queue_input_pos = pkt->pos + udp->queue[udp->next_seq]->size -
sizeof(stream_udp_header_t);
+ if(udp->queue[udp->next_seq]->size > sizeof(stream_udp_header_t))
+ this->block_buffer->put(this->block_buffer, udp->queue[udp->next_seq]);
+ else
+ udp->queue[udp->next_seq]->free_buffer(udp->queue[udp->next_seq]);
+
udp->queue[udp->next_seq] = NULL;
udp->queued --;
INCSEQ(udp->next_seq);
-
if(udp->resend_requested)
udp->resend_requested --;
}
@@ -3468,7 +3484,8 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
INCSEQ(current_seq);
printf_control(this, "UDP RESEND %d-%d %" PRIu64 "\r\n",
- udp->next_seq, PREVSEQ(current_seq), udp->queue_input_pos);
+ udp->next_seq, PREVSEQ(current_seq),
+ udp->queue_input_pos);
udp->resend_requested =
(current_seq + (UDP_SEQ_MASK+1) - udp->next_seq) & UDP_SEQ_MASK;
@@ -3477,8 +3494,8 @@ static int vdr_plugin_read_net_udp(vdr_input_plugin_t *this)
}
}
- /* Link quality statistics */
#ifdef LOG_UDP
+ /* Link quality statistics */
udp->received_frames++;
if(udp->received_frames >= 1000) {
if(udp->missed_frames)
@@ -3719,6 +3736,11 @@ static void track_audio_stream_change(vdr_input_plugin_t *this, buf_element_t *b
}
}
+//#define CACHE_FIRST_IFRAME
+#ifdef CACHE_FIRST_IFRAME
+# include "cache_iframe.c"
+#endif
+
static off_t vdr_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len)
{