#endif
}
+/*
void player_full_flush(rtsp_conn_info *conn) {
debug(3, "player_full_flush");
// this basically flushes everything from the player
if (flush_needed)
player_flush(rtpTimestamp, conn);
}
+*/
-int player_play(rtsp_conn_info *conn) {
+// perpare_to_play and play are split so that we can get the capabilities of the
+// dac etc. before initialising any decoders etc.
+// for example, if we have 32-bit DACs, we can ask for 32 bit decodes
+
+int player_prepare_to_play(rtsp_conn_info *conn) {
// need to use conn in place of stream below. Need to put the stream as a parameter to he
if (conn->player_thread != NULL)
die("Trying to create a second player thread for this RTSP session");
// call on the output device to prepare itself
if ((config.output) && (config.output->prepare))
config.output->prepare();
+ return 0;
+}
+int player_play(rtsp_conn_info *conn) {
pthread_t *pt = malloc(sizeof(pthread_t));
if (pt == NULL)
die("Couldn't allocate space for pthread_t");
int32_t modulo_32_offset(uint32_t from, uint32_t to);
+int player_prepare_to_play(rtsp_conn_info *conn);
int player_play(rtsp_conn_info *conn);
int player_stop(rtsp_conn_info *conn);
void player_volume(double f, rtsp_conn_info *conn);
void player_volume_without_notification(double f, rtsp_conn_info *conn);
void player_flush(uint32_t timestamp, rtsp_conn_info *conn);
-void player_full_flush(rtsp_conn_info *conn);
+// void player_full_flush(rtsp_conn_info *conn);
void player_put_packet(int original_format, seq_t seqno, uint32_t actual_timestamp, uint8_t *data,
int len, rtsp_conn_info *conn);
int64_t monotonic_timestamp(uint32_t timestamp,
}
}
-void add_flush_request(int flushNow, uint32_t flushFromSeq, uint32_t flushFromTS,
- uint32_t flushUntilSeq, uint32_t flushUntilTS, rtsp_conn_info *conn) {
- // immediate flush requests are added sequentially. Don't know how more than one could arise, TBH
- flush_request_t **t = &conn->flush_requests;
- int done = 0;
- do {
- flush_request_t *u = *t;
- if ((u == NULL) || ((u->flushNow == 0) && (flushNow != 0)) ||
- (flushFromSeq < u->flushFromSeq) ||
- ((flushFromSeq == u->flushFromSeq) && (flushFromTS < u->flushFromTS))) {
- flush_request_t *n = (flush_request_t *)calloc(sizeof(flush_request_t), 1);
- n->flushNow = flushNow;
- n->flushFromSeq = flushFromSeq;
- n->flushFromTS = flushFromTS;
- n->flushUntilSeq = flushUntilSeq;
- n->flushUntilTS = flushUntilTS;
- n->next = u;
- *t = n;
- done = 1;
- } else {
- t = &u->next;
- }
- } while (done == 0);
-}
-
-void display_all_flush_requests(rtsp_conn_info *conn) {
- if (conn->flush_requests == NULL) {
- debug(1, "No flush requests.");
- } else {
- flush_request_t *t = conn->flush_requests;
- do {
- if (t->flushNow) {
- debug(1, "immediate flush to untilSeq: %u, untilTS: %u.", t->flushUntilSeq,
- t->flushUntilTS);
- } else {
- debug(1, "fromSeq: %u, fromTS: %u, to untilSeq: %u, untilTS: %u.", t->flushFromSeq,
- t->flushFromTS, t->flushUntilSeq, t->flushUntilTS);
- }
- t = t->next;
- } while (t != NULL);
- }
-}
-
// park a null at the line ending, and return the next line pointer
// accept \r, \n, or \r\n
static char *nextline(char *in, int inbuf) {
#ifdef CONFIG_AIRPLAY_2
+void add_flush_request(int flushNow, uint32_t flushFromSeq, uint32_t flushFromTS,
+ uint32_t flushUntilSeq, uint32_t flushUntilTS, rtsp_conn_info *conn) {
+ // immediate flush requests are added sequentially. Don't know how more than one could arise, TBH
+ flush_request_t **t = &conn->flush_requests;
+ int done = 0;
+ do {
+ flush_request_t *u = *t;
+ if ((u == NULL) || ((u->flushNow == 0) && (flushNow != 0)) ||
+ (flushFromSeq < u->flushFromSeq) ||
+ ((flushFromSeq == u->flushFromSeq) && (flushFromTS < u->flushFromTS))) {
+ flush_request_t *n = (flush_request_t *)calloc(sizeof(flush_request_t), 1);
+ n->flushNow = flushNow;
+ n->flushFromSeq = flushFromSeq;
+ n->flushFromTS = flushFromTS;
+ n->flushUntilSeq = flushUntilSeq;
+ n->flushUntilTS = flushUntilTS;
+ n->next = u;
+ *t = n;
+ done = 1;
+ } else {
+ t = &u->next;
+ }
+ } while (done == 0);
+}
+
+void display_all_flush_requests(rtsp_conn_info *conn) {
+ if (conn->flush_requests == NULL) {
+ debug(1, "No flush requests.");
+ } else {
+ flush_request_t *t = conn->flush_requests;
+ do {
+ if (t->flushNow) {
+ debug(1, "immediate flush to untilSeq: %u, untilTS: %u.", t->flushUntilSeq,
+ t->flushUntilTS);
+ } else {
+ debug(1, "fromSeq: %u, fromTS: %u, to untilSeq: %u, untilTS: %u.", t->flushFromSeq,
+ t->flushFromTS, t->flushUntilSeq, t->flushUntilTS);
+ }
+ t = t->next;
+ } while (t != NULL);
+ }
+}
+
int rtsp_message_contains_plist(rtsp_message *message) {
int reply = 0; // assume there is no plist in the message
if ((message->contentlength >= strlen("bplist00")) &&
if (have_play_lock(conn)) {
if (conn->player_thread)
warn("Connection %d: RECORD: Duplicate RECORD message -- ignored", conn->connection_number);
- else
+ else {
+ player_prepare_to_play(conn);
player_play(conn); // the thread better be 0
+ }
resp->respcode = 200;
// I think this is for telling the client what the absolute minimum latency
else
debug(1, "No timing peer list!");
+ player_prepare_to_play(conn);
player_play(conn);
conn->rtp_running = 1; // hack!
conn->input_bit_depth = 16;
conn->input_bytes_per_frame = conn->input_num_channels * ((conn->input_bit_depth + 7) / 8);
+ player_prepare_to_play(conn);
player_play(conn);
conn->rtp_running = 1; // hack!