]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Improve the scanner to start and stop properly and to release track data when remote...
authorMike Brady <mikebrady@eircom.net>
Sat, 7 Apr 2018 12:22:38 +0000 (13:22 +0100)
committerMike Brady <mikebrady@eircom.net>
Sat, 7 Apr 2018 12:22:38 +0000 (13:22 +0100)
common.h
dacp.c
metadata_hub.c
metadata_hub.h
mpris-service.c
shairport.c

index 9daacf994bca3fe6aded2354c7b2ec97949ade41..50b7a0fedf0c90759a75c07846539d1203626342 100644 (file)
--- a/common.h
+++ b/common.h
@@ -173,10 +173,14 @@ typedef struct {
 
 #ifdef HAVE_METADATA_HUB
   char *cover_art_cache_dir;
-  int scan_interval_when_active; // number of seconds between DACP server scans when playing something (1)
-  int scan_interval_when_inactive; // number of seconds between DACP server scans playing nothing (3)
-  int scan_max_bad_response_count; // number of successive bad results to ignore before giving up (10) 
-  int scan_max_inactive_count; // number of scans to do before stopping if not made active again (about 15 minutes worth)
+  int scan_interval_when_active;   // number of seconds between DACP server scans when playing
+                                   // something (1)
+  int scan_interval_when_inactive; // number of seconds between DACP server scans playing nothing
+                                   // (3)
+  int scan_max_bad_response_count; // number of successive bad results to ignore before giving up
+                                   // (10)
+  int scan_max_inactive_count;     // number of scans to do before stopping if not made active again
+                                   // (about 15 minutes worth)
 #endif
   int disable_resend_requests; // set this to stop resend request being made for missing packets
 
diff --git a/dacp.c b/dacp.c
index a7d0679f054bbb9cb013ede143bf0646a68042ff..16cfe3e022c265aef250f95f2bd57731c0c2f801 100644 (file)
--- a/dacp.c
+++ b/dacp.c
@@ -302,7 +302,6 @@ void relinquish_dacp_server_information(rtsp_conn_info *conn) {
 // the conversation number
 // Thus, we can keep the DACP port that might have previously been discovered
 void set_dacp_server_information(rtsp_conn_info *conn) {
-  debug(1, "set_dacp_server_information.");  
   sps_pthread_mutex_timedlock(
       &dacp_server_information_lock, 500000,
       "set_dacp_server_information couldn't get DACP server information lock in 0.5 second!.", 2);
@@ -314,6 +313,8 @@ void set_dacp_server_information(rtsp_conn_info *conn) {
     dacp_server.connection_family = conn->connection_ip_family;
     dacp_server.scope_id = conn->self_scope_id;
     strncpy(dacp_server.ip_string, conn->client_ip_string, INET6_ADDRSTRLEN);
+    debug(1, "set_dacp_server_information set IP to \"%s\" and DACP id to \"%s\".",
+          dacp_server.ip_string, dacp_server.dacp_id);
 
     if (dacp_server.port_monitor_private_storage) // if there's is a monitor already active...
       mdns_dacp_dont_monitor(dacp_server.port_monitor_private_storage); // let it go.
@@ -334,15 +335,18 @@ void set_dacp_server_information(rtsp_conn_info *conn) {
     metadata_hub_modify_epilog(ch);
   } else {
     if (dacp_server.port) {
-      debug(1,"Enable scanning.");
+      debug(1, "Enable scanning.");
       dacp_server.scan_enable = 1;
-      metadata_hub_modify_prolog();
-      int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
-      metadata_store.dacp_server_active = dacp_server.scan_enable;
-      metadata_hub_modify_epilog(ch);
+      //      metadata_hub_modify_prolog();
+      //      int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
+      //      metadata_store.dacp_server_active = dacp_server.scan_enable;
+      //      metadata_hub_modify_epilog(ch);
     }
   }
-  dacp_server.active_remote_id = conn->dacp_active_remote; // even if the dacp_id remains the same, the active remote will change.
+  dacp_server.active_remote_id = conn->dacp_active_remote; // even if the dacp_id remains the same,
+                                                           // the active remote will change.
+  debug(1, "set_dacp_server_information set active-remote id to %" PRIu32 ".",
+        dacp_server.active_remote_id);
   pthread_cond_signal(&dacp_server_information_cv);
   pthread_mutex_unlock(&dacp_server_information_lock);
 }
@@ -358,16 +362,18 @@ void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) {
     dacp_server.port = port;
     if (port == 0)
       dacp_server.scan_enable = 0;
-    else
+    else {
       dacp_server.scan_enable = 1;
-    metadata_hub_modify_prolog();
-    int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
-    metadata_store.dacp_server_active = dacp_server.scan_enable;
-    metadata_hub_modify_epilog(ch);
-    pthread_cond_signal(&dacp_server_information_cv);
+      debug(1, "dacp_monitor_port_update_callback enables scan");
+    }
+    //    metadata_hub_modify_prolog();
+    //    int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
+    //    metadata_store.dacp_server_active = dacp_server.scan_enable;
+    //    metadata_hub_modify_epilog(ch);
   } else {
     debug(1, "dacp port monitor reporting on an out-of-use remote.");
   }
+  pthread_cond_signal(&dacp_server_information_cv);
   pthread_mutex_unlock(&dacp_server_information_lock);
 }
 void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
@@ -386,346 +392,367 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
     while (dacp_server.scan_enable == 0) {
       // debug(1, "Wait for a valid DACP port");
       pthread_cond_wait(&dacp_server_information_cv, &dacp_server_information_lock);
-      debug(1,"Wake up with dacp_server.scan_enable == %d.",dacp_server.scan_enable);
+      //      debug(1,"Wake up with dacp_server.scan_enable == %d.",dacp_server.scan_enable);
     }
     scan_index++;
     int32_t the_volume;
     result = dacp_get_volume(&the_volume); // just want the http code
-    
+
     if ((result == 496) || (result == 403) || (result == 501)) {
       bad_result_count++;
       // debug(1,"Bad Scan : %d.",result);
     } else
-      bad_result_count=0;
-    
-    if (metadata_store.player_thread_active==0)
+      bad_result_count = 0;
+
+    if (metadata_store.player_thread_active == 0)
       idle_scan_count++;
     else
       idle_scan_count = 0;
-      
-    debug(1,"HTTP Result: %d, Bad Scan Count: %d, Idle Scan Count: %d.",result,bad_result_count,idle_scan_count);
 
-    if ((bad_result_count == config.scan_max_bad_response_count) || (idle_scan_count == config.scan_max_inactive_count)) {
-      debug(1,"DACP server status scanning stopped.");
+    debug(1, "HTTP Result: %d, Bad Scan Count: %d, Idle Scan Count: %d.", result, bad_result_count,
+          idle_scan_count);
+
+    if ((bad_result_count == config.scan_max_bad_response_count) ||
+        (idle_scan_count == config.scan_max_inactive_count)) {
+      debug(1, "DACP server status scanning stopped.");
       dacp_server.scan_enable = 0;
       bad_result_count = 0;
       idle_scan_count = 0;
       metadata_hub_modify_prolog();
-      int ch = metadata_store.dacp_server_active != 0;
+      int ch = (metadata_store.dacp_server_active != 0) ||
+               (metadata_store.advanced_dacp_server_active != 0);
       metadata_store.dacp_server_active = 0;
-      debug(1,"setting dacp_server_active to %d with an update flag value of %d",metadata_store.dacp_server_active,ch);
+      metadata_store.advanced_dacp_server_active = 0;
+      debug(1, "setting dacp_server_active and advanced_dacp_server_active to 0 with an update "
+               "flag value of %d",
+            ch);
       metadata_hub_modify_epilog(ch);
     }
     pthread_mutex_unlock(&dacp_server_information_lock);
     // debug(1, "DACP Server ID \"%u\" at \"%s:%u\", scan %d.", dacp_server.active_remote_id,
     //      dacp_server.ip_string, dacp_server.port, scan_index);
 
-    int transient_problem = (result == 494) || (result == 495);
-    if (!transient_problem) { // this just means that it couldn't send the query because something
-                              // else
-                              // was sending a command or something
-      int adv = (result == 200);
-      // a result of 200 means the advanced features of, e.g., iTunes, are available
-      // so, turn the advanced_dacp_server flag on or off and flag if it's changed.
-      metadata_hub_modify_prolog();
-      int diff = metadata_store.advanced_dacp_server_active != adv;
-      if (diff) {
-        metadata_store.advanced_dacp_server_active = adv;
-        debug(1, "Setting dacp_server_active to %d because of a response of %d.", adv, result);
+    if (dacp_server.scan_enable ==
+        1) { // if it hasn't been turned off, continue looking for information.
+      int transient_problem =
+          (result == 494) ||
+          (result == 495); // this just means that it couldn't send the query because something
+                           // else
+                           // was sending a command or something
+      if ((!transient_problem) && (bad_result_count == 0) && (idle_scan_count == 0) &&
+          (dacp_server.scan_enable == 1)) {
+
+        // Any other result means that the DACP server is active, but not providing advanced
+        // features
+
+        metadata_hub_modify_prolog();
+        int inactive = metadata_store.dacp_server_active == 0;
+        if (inactive) {
+          metadata_store.dacp_server_active = 1;
+          debug(1, "Setting dacp_server_active to active because of a response of %d.", result);
+        }
+        int same = metadata_store.advanced_dacp_server_active == (result == 200);
+        if (!same) {
+          metadata_store.advanced_dacp_server_active = (result == 200);
+          debug(1, "Setting dacp_advanced_server_active to %d because of a response of %d.", (result == 200),
+                result);
+        }
+        metadata_hub_modify_epilog(inactive + (!same));
       }
-      metadata_hub_modify_epilog(diff);
-    }
 
-    if (result == 200) {
-      metadata_hub_modify_prolog();
-      int diff = metadata_store.speaker_volume != the_volume;
-      if (diff)
-        metadata_store.speaker_volume = the_volume;
-      metadata_hub_modify_epilog(diff);
-
-      ssize_t le;
-      char *response = NULL;
-      int32_t item_size;
-      char command[1024] = "";
-      snprintf(command, sizeof(command) - 1, "playstatusupdate?revision-number=%d",
-               revision_number);
-      // debug(1,"Command: \"%s\"",command);
-      result = dacp_send_command(command, &response, &le);
-      // debug(1,"Response to \"%s\" is %d.",command,result);
       if (result == 200) {
-        // if (0) {
-        char *sp = response;
-        if (le >= 8) {
-          // here start looking for the contents of the status update
-          if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status
-            // here, we know that we are receiving playerstatusupdates, so set a flag
-            metadata_hub_modify_prolog();
-            // debug(1, "playstatusupdate release track metadata");
-            // metadata_hub_reset_track_metadata();
-            // metadata_store.playerstatusupdates_are_received = 1;
-            sp -= item_size; // drop down into the array -- don't skip over it
-            le -= 8;
-            // char typestring[5];
-            // we need to acquire the metadata data structure and possibly update it
-            while (le >= 8) {
-              uint32_t type = dacp_tlv_crawl(&sp, &item_size);
-              le -= item_size + 8;
-              char *t;
-              // char u;
-              // char *st;
-              int32_t r;
-              // uint64_t v;
-              // int i;
-
-              switch (type) {
-              case 'cmsr': // revision number
-                t = sp - item_size;
-                revision_number = ntohl(*(uint32_t *)(t));
-                // debug(1,"    Serial Number: %d", revision_number);
-                break;
-              case 'caps': // play status
-                t = sp - item_size;
-                r = *(unsigned char *)(t);
-                switch (r) {
-                case 2:
-                  if (metadata_store.play_status != PS_STOPPED) {
-                    metadata_store.play_status = PS_STOPPED;
-                    debug(2, "Play status is \"stopped\".");
-                  }
+        metadata_hub_modify_prolog();
+        int diff = metadata_store.speaker_volume != the_volume;
+        if (diff)
+          metadata_store.speaker_volume = the_volume;
+        metadata_hub_modify_epilog(diff);
+
+        ssize_t le;
+        char *response = NULL;
+        int32_t item_size;
+        char command[1024] = "";
+        snprintf(command, sizeof(command) - 1, "playstatusupdate?revision-number=%d",
+                 revision_number);
+        // debug(1,"Command: \"%s\"",command);
+        result = dacp_send_command(command, &response, &le);
+        // debug(1,"Response to \"%s\" is %d.",command,result);
+        if (result == 200) {
+          // if (0) {
+          char *sp = response;
+          if (le >= 8) {
+            // here start looking for the contents of the status update
+            if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status
+              // here, we know that we are receiving playerstatusupdates, so set a flag
+              metadata_hub_modify_prolog();
+              // debug(1, "playstatusupdate release track metadata");
+              // metadata_hub_reset_track_metadata();
+              // metadata_store.playerstatusupdates_are_received = 1;
+              sp -= item_size; // drop down into the array -- don't skip over it
+              le -= 8;
+              // char typestring[5];
+              // we need to acquire the metadata data structure and possibly update it
+              while (le >= 8) {
+                uint32_t type = dacp_tlv_crawl(&sp, &item_size);
+                le -= item_size + 8;
+                char *t;
+                // char u;
+                // char *st;
+                int32_t r;
+                // uint64_t v;
+                // int i;
+
+                switch (type) {
+                case 'cmsr': // revision number
+                  t = sp - item_size;
+                  revision_number = ntohl(*(uint32_t *)(t));
+                  // debug(1,"    Serial Number: %d", revision_number);
                   break;
-                case 3:
-                  if (metadata_store.play_status != PS_PAUSED) {
-                    metadata_store.play_status = PS_PAUSED;
-                    debug(2, "Play status is \"paused\".");
+                case 'caps': // play status
+                  t = sp - item_size;
+                  r = *(unsigned char *)(t);
+                  switch (r) {
+                  case 2:
+                    if (metadata_store.play_status != PS_STOPPED) {
+                      metadata_store.play_status = PS_STOPPED;
+                      debug(2, "Play status is \"stopped\".");
+                    }
+                    break;
+                  case 3:
+                    if (metadata_store.play_status != PS_PAUSED) {
+                      metadata_store.play_status = PS_PAUSED;
+                      debug(2, "Play status is \"paused\".");
+                    }
+                    break;
+                  case 4:
+                    if (metadata_store.play_status != PS_PLAYING) {
+                      metadata_store.play_status = PS_PLAYING;
+                      debug(2, "Play status changed to \"playing\".");
+                    }
+                    break;
+                  default:
+                    debug(1, "Unrecognised play status %d received.", r);
+                    break;
                   }
                   break;
-                case 4:
-                  if (metadata_store.play_status != PS_PLAYING) {
-                    metadata_store.play_status = PS_PLAYING;
-                    debug(2, "Play status changed to \"playing\".");
+                case 'cash': // shuffle status
+                  t = sp - item_size;
+                  r = *(unsigned char *)(t);
+                  switch (r) {
+                  case 0:
+                    if (metadata_store.shuffle_status != SS_OFF) {
+                      metadata_store.shuffle_status = SS_OFF;
+                      debug(2, "Shuffle status is \"off\".");
+                    }
+                    break;
+                  case 1:
+                    if (metadata_store.shuffle_status != SS_ON) {
+                      metadata_store.shuffle_status = SS_ON;
+                      debug(2, "Shuffle status is \"on\".");
+                    }
+                    break;
+                  default:
+                    debug(1, "Unrecognised shuffle status %d received.", r);
+                    break;
                   }
                   break;
-                default:
-                  debug(1, "Unrecognised play status %d received.", r);
-                  break;
-                }
-                break;
-              case 'cash': // shuffle status
-                t = sp - item_size;
-                r = *(unsigned char *)(t);
-                switch (r) {
-                case 0:
-                  if (metadata_store.shuffle_status != SS_OFF) {
-                    metadata_store.shuffle_status = SS_OFF;
-                    debug(2, "Shuffle status is \"off\".");
+                case 'carp': // repeat status
+                  t = sp - item_size;
+                  r = *(unsigned char *)(t);
+                  switch (r) {
+                  case 0:
+                    if (metadata_store.repeat_status != RS_OFF) {
+                      metadata_store.repeat_status = RS_OFF;
+                      debug(2, "Repeat status is \"none\".");
+                    }
+                    break;
+                  case 1:
+                    if (metadata_store.repeat_status != RS_ONE) {
+                      metadata_store.repeat_status = RS_ONE;
+                      debug(2, "Repeat status is \"one\".");
+                    }
+                    break;
+                  case 2:
+                    if (metadata_store.repeat_status != RS_ALL) {
+                      metadata_store.repeat_status = RS_ALL;
+                      debug(2, "Repeat status is \"all\".");
+                    }
+                    break;
+                  default:
+                    debug(1, "Unrecognised repeat status %d received.", r);
+                    break;
                   }
                   break;
-                case 1:
-                  if (metadata_store.shuffle_status != SS_ON) {
-                    metadata_store.shuffle_status = SS_ON;
-                    debug(2, "Shuffle status is \"on\".");
+                /*
+                case 'cann': // track name
+                  t = sp - item_size;
+                  if ((metadata_store.track_name == NULL) ||
+                      (strncmp(metadata_store.track_name, t, item_size) != 0)) {
+                    if (metadata_store.track_name)
+                      free(metadata_store.track_name);
+                    metadata_store.track_name = strndup(t, item_size);
+                    debug(1, "Track name changed to: \"%s\"", metadata_store.track_name);
+                    metadata_store.track_name_changed = 1;
+                    metadata_store.changed = 1;
                   }
                   break;
-                default:
-                  debug(1, "Unrecognised shuffle status %d received.", r);
+                case 'cana': // artist name
+                  t = sp - item_size;
+                  if ((metadata_store.artist_name == NULL) ||
+                      (strncmp(metadata_store.artist_name, t, item_size) != 0)) {
+                    if (metadata_store.artist_name)
+                      free(metadata_store.artist_name);
+                    metadata_store.artist_name = strndup(t, item_size);
+                    debug(1, "Artist name changed to: \"%s\"", metadata_store.artist_name);
+                    metadata_store.artist_name_changed = 1;
+                    metadata_store.changed = 1;
+                  }
                   break;
-                }
-                break;
-              case 'carp': // repeat status
-                t = sp - item_size;
-                r = *(unsigned char *)(t);
-                switch (r) {
-                case 0:
-                  if (metadata_store.repeat_status != RS_OFF) {
-                    metadata_store.repeat_status = RS_OFF;
-                    debug(2, "Repeat status is \"none\".");
+                case 'canl': // album name
+                  t = sp - item_size;
+                  if ((metadata_store.album_name == NULL) ||
+                      (strncmp(metadata_store.album_name, t, item_size) != 0)) {
+                    if (metadata_store.album_name)
+                      free(metadata_store.album_name);
+                    metadata_store.album_name = strndup(t, item_size);
+                    debug(1, "Album name changed to: \"%s\"", metadata_store.album_name);
+                    metadata_store.album_name_changed = 1;
+                    metadata_store.changed = 1;
                   }
                   break;
-                case 1:
-                  if (metadata_store.repeat_status != RS_ONE) {
-                    metadata_store.repeat_status = RS_ONE;
-                    debug(2, "Repeat status is \"one\".");
+                case 'cang': // genre
+                  t = sp - item_size;
+                  if ((metadata_store.genre == NULL) ||
+                      (strncmp(metadata_store.genre, t, item_size) != 0)) {
+                    if (metadata_store.genre)
+                      free(metadata_store.genre);
+                    metadata_store.genre = strndup(t, item_size);
+                    debug(1, "Genre changed to: \"%s\"", metadata_store.genre);
+                    metadata_store.genre_changed = 1;
+                    metadata_store.changed = 1;
                   }
                   break;
-                case 2:
-                  if (metadata_store.repeat_status != RS_ALL) {
-                    metadata_store.repeat_status = RS_ALL;
-                    debug(2, "Repeat status is \"all\".");
+                case 'canp': // nowplaying 4 ids: dbid, plid, playlistItem, itemid (from mellowware
+                --
+                             // see reference above)
+                  t = sp - item_size;
+                  if (memcmp(metadata_store.item_composite_id, t,
+                             sizeof(metadata_store.item_composite_id)) != 0) {
+                    memcpy(metadata_store.item_composite_id, t,
+                           sizeof(metadata_store.item_composite_id));
+
+                    char st[33];
+                    char *pt = st;
+                    int it;
+                    for (it = 0; it < 16; it++) {
+                      sprintf(pt, "%02X", metadata_store.item_composite_id[it]);
+                      pt += 2;
+                    }
+                    *pt = 0;
+                    // debug(1, "Item composite ID set to 0x%s.", st);
+                    metadata_store.item_id_changed = 1;
+                    metadata_store.changed = 1;
                   }
                   break;
-                default:
-                  debug(1, "Unrecognised repeat status %d received.", r);
+                */
+                case 'astm':
+                  t = sp - item_size;
+                  r = ntohl(*(uint32_t *)(t));
+                  if (metadata_store.track_metadata)
+                    metadata_store.track_metadata->songtime_in_milliseconds =
+                        ntohl(*(uint32_t *)(t));
                   break;
-                }
-                break;
-              /*
-              case 'cann': // track name
-                t = sp - item_size;
-                if ((metadata_store.track_name == NULL) ||
-                    (strncmp(metadata_store.track_name, t, item_size) != 0)) {
-                  if (metadata_store.track_name)
-                    free(metadata_store.track_name);
-                  metadata_store.track_name = strndup(t, item_size);
-                  debug(1, "Track name changed to: \"%s\"", metadata_store.track_name);
-                  metadata_store.track_name_changed = 1;
-                  metadata_store.changed = 1;
-                }
-                break;
-              case 'cana': // artist name
-                t = sp - item_size;
-                if ((metadata_store.artist_name == NULL) ||
-                    (strncmp(metadata_store.artist_name, t, item_size) != 0)) {
-                  if (metadata_store.artist_name)
-                    free(metadata_store.artist_name);
-                  metadata_store.artist_name = strndup(t, item_size);
-                  debug(1, "Artist name changed to: \"%s\"", metadata_store.artist_name);
-                  metadata_store.artist_name_changed = 1;
-                  metadata_store.changed = 1;
-                }
-                break;
-              case 'canl': // album name
-                t = sp - item_size;
-                if ((metadata_store.album_name == NULL) ||
-                    (strncmp(metadata_store.album_name, t, item_size) != 0)) {
-                  if (metadata_store.album_name)
-                    free(metadata_store.album_name);
-                  metadata_store.album_name = strndup(t, item_size);
-                  debug(1, "Album name changed to: \"%s\"", metadata_store.album_name);
-                  metadata_store.album_name_changed = 1;
-                  metadata_store.changed = 1;
-                }
-                break;
-              case 'cang': // genre
-                t = sp - item_size;
-                if ((metadata_store.genre == NULL) ||
-                    (strncmp(metadata_store.genre, t, item_size) != 0)) {
-                  if (metadata_store.genre)
-                    free(metadata_store.genre);
-                  metadata_store.genre = strndup(t, item_size);
-                  debug(1, "Genre changed to: \"%s\"", metadata_store.genre);
-                  metadata_store.genre_changed = 1;
-                  metadata_store.changed = 1;
-                }
-                break;
-              case 'canp': // nowplaying 4 ids: dbid, plid, playlistItem, itemid (from mellowware --
-                           // see reference above)
-                t = sp - item_size;
-                if (memcmp(metadata_store.item_composite_id, t,
-                           sizeof(metadata_store.item_composite_id)) != 0) {
-                  memcpy(metadata_store.item_composite_id, t,
-                         sizeof(metadata_store.item_composite_id));
-
-                  char st[33];
-                  char *pt = st;
-                  int it;
-                  for (it = 0; it < 16; it++) {
-                    sprintf(pt, "%02X", metadata_store.item_composite_id[it]);
-                    pt += 2;
-                  }
-                  *pt = 0;
-                  // debug(1, "Item composite ID set to 0x%s.", st);
-                  metadata_store.item_id_changed = 1;
-                  metadata_store.changed = 1;
-                }
-                break;
-              */
-              case 'astm':
-                t = sp - item_size;
-                r = ntohl(*(uint32_t *)(t));
-                if (metadata_store.track_metadata)
-                  metadata_store.track_metadata->songtime_in_milliseconds = ntohl(*(uint32_t *)(t));
-                break;
-
-              /*
-                          case 'mstt':
-                          case 'cant':
-                          case 'cast':
-                          case 'cmmk':
-                          case 'caas':
-                          case 'caar':
-                            t = sp - item_size;
-                            r = ntohl(*(uint32_t *)(t));
-                            printf("    %d", r);
-                            printf("    (0x");
-                            t = sp - item_size;
-                            for (i = 0; i < item_size; i++) {
-                              printf("%02x", *t & 0xff);
-                              t++;
-                            }
-                            printf(")");
-                            break;
-                          case 'asai':
-                            t = sp - item_size;
-                            s = ntohl(*(uint32_t *)(t));
-                            s = s << 32;
-                            t += 4;
-                            v = (ntohl(*(uint32_t *)(t))) & 0xffffffff;
-                            s += v;
-                            printf("    %lu", s);
-                            printf("    (0x");
-                            t = sp - item_size;
-                            for (i = 0; i < item_size; i++) {
-                              printf("%02x", *t & 0xff);
-                              t++;
-                            }
-                            printf(")");
-                            break;
-               */
-              default:
+
                 /*
-                  printf("    0x");
-                  t = sp - item_size;
-                  for (i = 0; i < item_size; i++) {
-                    printf("%02x", *t & 0xff);
-                    t++;
-                  }
+                            case 'mstt':
+                            case 'cant':
+                            case 'cast':
+                            case 'cmmk':
+                            case 'caas':
+                            case 'caar':
+                              t = sp - item_size;
+                              r = ntohl(*(uint32_t *)(t));
+                              printf("    %d", r);
+                              printf("    (0x");
+                              t = sp - item_size;
+                              for (i = 0; i < item_size; i++) {
+                                printf("%02x", *t & 0xff);
+                                t++;
+                              }
+                              printf(")");
+                              break;
+                            case 'asai':
+                              t = sp - item_size;
+                              s = ntohl(*(uint32_t *)(t));
+                              s = s << 32;
+                              t += 4;
+                              v = (ntohl(*(uint32_t *)(t))) & 0xffffffff;
+                              s += v;
+                              printf("    %lu", s);
+                              printf("    (0x");
+                              t = sp - item_size;
+                              for (i = 0; i < item_size; i++) {
+                                printf("%02x", *t & 0xff);
+                                t++;
+                              }
+                              printf(")");
+                              break;
                  */
-                break;
+                default:
+                  /*
+                    printf("    0x");
+                    t = sp - item_size;
+                    for (i = 0; i < item_size; i++) {
+                      printf("%02x", *t & 0xff);
+                      t++;
+                    }
+                   */
+                  break;
+                }
+                // printf("\n");
               }
-              // printf("\n");
-            }
 
-            // finished possibly writing to the metadata hub
-            metadata_hub_modify_epilog(1);
+              // finished possibly writing to the metadata hub
+              metadata_hub_modify_epilog(1);
+            } else {
+              debug(1, "Status Update not found.\n");
+            }
           } else {
-            debug(1, "Status Update not found.\n");
+            debug(1, "Can't find any content in playerstatusupdate request");
           }
-        } else {
-          debug(1, "Can't find any content in playerstatusupdate request");
-        }
-      } /* else {
-        if (result != 403)
-          debug(1, "Unexpected response %d to playerstatusupdate request", result);
-      } */
+        } /* else {
+          if (result != 403)
+            debug(1, "Unexpected response %d to playerstatusupdate request", result);
+        } */
+        if (response) {
+          free(response);
+          response = NULL;
+        };
+      };
+      /*
+      strcpy(command,"nowplayingartwork?mw=320&mh=320");
+      debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
       if (response) {
         free(response);
         response = NULL;
-      };
-    };
-    /*
-    strcpy(command,"nowplayingartwork?mw=320&mh=320");
-    debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
-    if (response) {
-      free(response);
-      response = NULL;
-    }
-    strcpy(command,"getproperty?properties=dmcp.volume");
-    debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
-    if (response) {
-      free(response);
-      response = NULL;
-    }
-    strcpy(command,"setproperty?dmcp.volume=100.000000");
-    debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
-    if (response) {
-      free(response);
-      response = NULL;
+      }
+      strcpy(command,"getproperty?properties=dmcp.volume");
+      debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
+      if (response) {
+        free(response);
+        response = NULL;
+      }
+      strcpy(command,"setproperty?dmcp.volume=100.000000");
+      debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le));
+      if (response) {
+        free(response);
+        response = NULL;
+      }
+      */
+      if (metadata_store.player_thread_active)
+        sleep(config.scan_interval_when_active);
+      else
+        sleep(config.scan_interval_when_inactive);
     }
-    */
-    if (metadata_store.player_thread_active)
-      sleep(config.scan_interval_when_active);
-    else
-      sleep(config.scan_interval_when_inactive);
   }
   debug(1, "DACP monitor thread exiting.");
   pthread_exit(NULL);
index 4d67b5ffaa809c58dfeead6e53348c91e2eab459..7018992b7c1e234a75161273b8ee1cf00aa40673 100644 (file)
@@ -135,6 +135,23 @@ void run_metadata_watchers(void) {
 void metadata_hub_modify_epilog(int modified) {
   // always run this after changing an entry or a sequence of entries in the metadata_hub
   // debug(1, "unlocking metadata hub for writing");
+  int m = 0;
+  if (metadata_store.dacp_server_active==0) {
+      // debug(1,"player_stop release track metadata and artwork");
+      // 
+    if (metadata_store.track_metadata) {
+      m = 1;
+      metadata_hub_release_track_metadata(metadata_store.track_metadata);
+      metadata_store.track_metadata = NULL;
+    }
+    if (metadata_store.cover_art_pathname) {
+      m = 1;
+      metadata_hub_release_track_artwork();  
+    }
+    if (m)
+      debug(1,"Release track metadata after dacp server goes inactive.");
+    modified += m;
+  }
   pthread_rwlock_unlock(&metadata_hub_re_lock);
   if (modified) {
     run_metadata_watchers();
@@ -476,10 +493,6 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
       metadata_hub_modify_prolog();
       metadata_store.player_thread_active = 0;
       metadata_store.player_state = PS_STOPPED;
-      // debug(1,"player_stop release track metadata and artwork");
-      //metadata_hub_release_track_metadata(metadata_store.track_metadata);
-      //metadata_store.track_metadata = NULL;
-      //metadata_hub_release_track_artwork();
       metadata_hub_modify_epilog(1);
     } break;
     case 'pfls': {
index 85b7354d2219122e7558aa29314d1140202fe2eb..3ffc0dc1b02f3b98d0ef81232bf31a9922fd52aa 100644 (file)
@@ -53,8 +53,8 @@ typedef struct metadata_bundle {
                    // server
   char *server_ip; // IP number used by Shairport Sync
   int player_thread_active; // true if a play thread is running
-  int dacp_server_active; // true if there's a reachable DACP server (assumed to be the Airplay
-                          // client) ; false otherwise
+  int dacp_server_active;   // true if there's a reachable DACP server (assumed to be the Airplay
+                            // client) ; false otherwise
   int advanced_dacp_server_active; // true if there's a reachable DACP server with iTunes
                                    // capabilitiues
                                    // ; false otherwise
index 27408972ed88f7c2c657143386a8d265a94af0ee..30a09e011d1eca5f3d15c606c2d286701b12b8a3 100644 (file)
@@ -106,15 +106,15 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused)
   int it;
   int non_zero = 0;
   if (argc->track_metadata) {
-  for (it = 0; it < 16; it++) {
-    if (argc->track_metadata->item_composite_id[it])
-      non_zero = 1;
-    sprintf(pt, "%02X", argc->track_metadata->item_composite_id[it]);
-    pt += 2;
-  }
+    for (it = 0; it < 16; it++) {
+      if (argc->track_metadata->item_composite_id[it])
+        non_zero = 1;
+      sprintf(pt, "%02X", argc->track_metadata->item_composite_id[it]);
+      pt += 2;
+    }
   }
   *pt = 0;
-  
+
   if (non_zero) {
     // debug(1, "Set ID using composite ID: \"0x%s\".", st);
     char trackidstring[1024];
index 871149834b454c4e1da82b7d148cca030465ef37..b9fe25b2cc6315eb6e242495eeb4e503884de534 100644 (file)
@@ -334,11 +334,17 @@ int parse_options(int argc, char **argv) {
   config.fixedLatencyOffset = 11025; // this sounds like it works properly.
 #ifdef HAVE_METADATA_HUB
   config.cover_art_cache_dir = "/tmp/shairport-sync/.cache/coverart";
-  config.scan_interval_when_active = 1; // number of seconds between DACP server scans when playing something
-  config.scan_interval_when_inactive = 3; // number of seconds between DACP server scans playing nothing
-  config.scan_max_bad_response_count = 10; // number of successive bad results to ignore before giving up 
-  config.scan_max_inactive_count = (24*60*60)/config.scan_interval_when_inactive; // number of scans to do before stopping if not made active again (24 hours )
-//  config.scan_max_inactive_count = 5; // number of scans to do before stopping if not made active again (15 minutes )
+  config.scan_interval_when_active =
+      1; // number of seconds between DACP server scans when playing something
+  config.scan_interval_when_inactive =
+      3; // number of seconds between DACP server scans playing nothing
+  config.scan_max_bad_response_count =
+      5; // number of successive bad results to ignore before giving up
+  config.scan_max_inactive_count =
+      (15 * 60) / config.scan_interval_when_inactive; // number of scans to do before stopping if
+                                                      // not made active again (15 minutes)
+//  config.scan_max_inactive_count = 5; // number of scans to do before stopping if not made active
+//  again (15 minutes )
 #endif
 
   // config_setting_t *setting;