uint32_t flush_limit = 0;
if (conn->ab_synced) {
- int frame_flushed;
do {
- frame_flushed = 0;
curframe = conn->audio_buffer + BUFIDX(conn->ab_read);
if ((conn->ab_read != conn->ab_write) &&
(curframe->ready)) { // it could be synced and empty, under
curframe->resend_level = 0;
flush_limit += curframe->length;
conn->ab_read = SUCCESSOR(conn->ab_read);
- frame_flushed = 1;
conn->initial_reference_time = 0;
conn->initial_reference_timestamp = 0;
}
debug(2, "Dropping flush request in buffer_get_frame");
conn->flush_rtp_timestamp = 0;
}
- } else {
- if (curframe->ready == 0)
- debug(1, "An unready frame was seen in a flush sequence!");
}
- } while ((conn->flush_rtp_timestamp != 0) && (flush_limit <= 8820) && (frame_flushed));
+ } while ((conn->flush_rtp_timestamp != 0) && (flush_limit <= 8820) && (curframe->ready == 0));
if (flush_limit == 8820) {
debug(1, "Flush hit the 8820 frame limit!");
int64_t sync_error, correction, drift;
} stats_t;
-void player_thread_cleanup_handler(void *arg) {
- debug(1, "player_thread_cleanup_handler called");
+void player_thread_initial_cleanup_handler(__attribute__((unused)) void *arg) {
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+ debug(3, "Connection %d: player thread main loop exit via player_thread_initial_cleanup_handler.", conn->connection_number);
+}
- debug(3, "Connection %d: player thread main loop exit.", conn->connection_number);
+void player_thread_cleanup_handler(void *arg) {
+ rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+ debug(3, "Connection %d: player thread main loop exit via player_thread_cleanup_handler.", conn->connection_number);
if (config.statistics_requested) {
int rawSeconds = (int)difftime(time(NULL), conn->playstart);
void *player_thread_func(void *arg) {
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
-
+ pthread_cleanup_push(player_thread_initial_cleanup_handler, arg);
conn->packet_count = 0;
conn->packet_count_since_flush = 0;
conn->previous_random_number = 0;
conn); // this sets up incoming rate, bit depth, channels.
// No pthread cancellation point in here
// This must be after init_decoder
- init_buffer(conn); // will need a corresponding deallocation
+ init_buffer(conn); // will need a corresponding deallocation. No cancellation points in here
if (conn->stream.encrypted) {
#ifdef CONFIG_MBEDTLS
debug(1, "DACP monitor already initialised?");
else
// this does not have pthread cancellation points in it (assuming avahi doesn't)
- conn->dapo_private_storage = mdns_dacp_monitor(conn->dacp_id); // ??
+ conn->dapo_private_storage = mdns_dacp_monitor(conn->dacp_id);
#endif
conn->framesProcessedInThisEpoch = 0;
}
}
- // set the default volume to whaterver it was before, as stored in the config airplay_volume
- debug(3, "Set initial volume to %f.", config.airplay_volume);
- player_volume(config.airplay_volume, conn); // ??
int64_t frames_to_drop = 0;
// create and start the timing, control and audio receiver threads
pthread_cleanup_push(player_thread_cleanup_handler, arg); // undo what's been done so far
+ // set the default volume to whaterver it was before, as stored in the config airplay_volume
+ debug(2, "Set initial volume to %f.", config.airplay_volume);
+ player_volume(config.airplay_volume, conn); // will contain a cancellation point if asked to wait
+
debug(2, "Play begin");
while (1) {
abuf_t *inframe = buffer_get_frame(conn); // this has cancellation point(s)
}
debug(1, "This should never be called.");
- pthread_cleanup_pop(1);
- pthread_exit(NULL);
+ pthread_cleanup_pop(1); // pop the cleanup handler
+ debug(1, "This should never be called either.");
+ pthread_cleanup_pop(1); // pop the initial cleanup handler
+ pthread_exit(NULL);
}
// takes the volume as specified by the airplay protocol
if (config.buffer_start_fill > BUFFER_FRAMES)
die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill,
BUFFER_FRAMES);
+ debug(1,"Executing the run_this_before_play_begins hook, if any.");
command_start();
-#ifdef CONFIG_METADATA
- debug(2, "pbeg");
- send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points
-#endif
+ debug(1,"Create a player thread...");
pthread_t *pt = malloc(sizeof(pthread_t));
if (pt == NULL)
die("Couldn't allocate space for pthread_t");
if (rc)
debug(1, "Error setting stack size for player_thread: %s", strerror(errno));
// finished initialising.
- pthread_create(pt, &tattr, player_thread_func, (void *)conn);
+ rc = pthread_create(pt, &tattr, player_thread_func, (void *)conn);
+ if (rc)
+ debug(1, "Error creating player_thread: %s", strerror(errno));
pthread_attr_destroy(&tattr);
+ debug(1,"Player thread successfully created.");
+#ifdef CONFIG_METADATA
+ debug(2, "pbeg");
+ send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points
+#endif
return 0;
}
int player_stop(rtsp_conn_info *conn) {
- int dl = debuglev;
- if (debuglev)
- debuglev = 3;
// note -- this may be called from another connection thread.
+ int dl = debuglev;
+ debuglev = 3;
debug(3, "player_stop");
if (conn->player_thread) {
debug(2, "player_thread cancel...");
debug(2, "pend");
send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points
#endif
- debuglev = dl;
+ debuglev = dl;
command_stop();
return 0;
} else {
- debug(3, "player_stop: player thread not running on connection %d.", conn->connection_number);
- debuglev = dl;
+ debug(3, "Connection %d: player thread already deleted.", conn->connection_number);
+ debuglev = dl;
return -1;
}
}