static bool httpd_output_encode_and_play(struct httpd_output *httpd, const void *chunk, size_t size, GError **error) { bool success; struct page *page; success = encoder_write(httpd->encoder, chunk, size, error); if (!success) return false; g_mutex_lock(httpd->mutex); g_list_foreach(httpd->clients, httpd_client_check_queue, NULL); g_mutex_unlock(httpd->mutex); while ((page = httpd_output_read_page(httpd)) != NULL) { g_mutex_lock(httpd->mutex); g_list_foreach(httpd->clients, httpd_client_send_page, page); g_mutex_unlock(httpd->mutex); page_unref(page); } return true; }
static void httpd_output_tag(struct audio_output *ao, const struct tag *tag) { struct httpd_output *httpd = (struct httpd_output *)ao; assert(tag != NULL); if (httpd->encoder->plugin->tag != NULL) { /* embed encoder tags */ struct page *page; /* flush the current stream, and end it */ encoder_pre_tag(httpd->encoder, NULL); httpd_output_encoder_to_clients(httpd); /* send the tag to the encoder - which starts a new stream now */ encoder_tag(httpd->encoder, tag, NULL); /* the first page generated by the encoder will now be used as the new "header" page, which is sent to all new clients */ page = httpd_output_read_page(httpd); if (page != NULL) { if (httpd->header != NULL) page_unref(httpd->header); httpd->header = page; httpd_output_broadcast_page(httpd, page); } } else { /* use Icy-Metadata */ if (httpd->metadata != NULL) page_unref (httpd->metadata); httpd->metadata = icy_server_metadata_page(tag, TAG_ALBUM, TAG_ARTIST, TAG_TITLE, TAG_NUM_OF_ITEM_TYPES); if (httpd->metadata != NULL) { g_mutex_lock(httpd->mutex); g_list_foreach(httpd->clients, httpd_send_metadata, httpd->metadata); g_mutex_unlock(httpd->mutex); } } }
/** * Broadcasts data from the encoder to all clients. */ static void httpd_output_encoder_to_clients(struct httpd_output *httpd) { struct page *page; g_mutex_lock(httpd->mutex); g_list_foreach(httpd->clients, httpd_client_check_queue, NULL); g_mutex_unlock(httpd->mutex); while ((page = httpd_output_read_page(httpd)) != NULL) { httpd_output_broadcast_page(httpd, page); page_unref(page); } }
static bool httpd_output_encoder_open(struct httpd_output *httpd, struct audio_format *audio_format, GError **error) { bool success; success = encoder_open(httpd->encoder, audio_format, error); if (!success) return false; /* we have to remember the encoder header, i.e. the first bytes of encoder output after opening it, because it has to be sent to every new client */ httpd->header = httpd_output_read_page(httpd); return true; }