summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2018-12-16 14:14:41 +0100
committerLars-Dominik Braun <lars@6xq.net>2020-08-09 08:42:11 +0200
commitbc6bd8a2b8b84a79dd77b81d6a25b661c5d1d1ca (patch)
tree3013cbf73ea3374d9974d251e11da87be7d1276b
parent7f6457aa9b7110869e89111c42651b1055728679 (diff)
downloadpianobar-bc6bd8a2b8b84a79dd77b81d6a25b661c5d1d1ca.tar.gz
pianobar-bc6bd8a2b8b84a79dd77b81d6a25b661c5d1d1ca.tar.bz2
pianobar-bc6bd8a2b8b84a79dd77b81d6a25b661c5d1d1ca.zip
Add optional debugging code
Compile *without* -DNDEBUG. The environment variable PIANOBAR_DEBUG accepts a bitfield which enables (1) network (2) audio (4) UI debug messages.
-rw-r--r--Makefile1
-rw-r--r--src/config.h7
-rw-r--r--src/debug.c29
-rw-r--r--src/debug.h64
-rw-r--r--src/main.c4
-rw-r--r--src/player.c17
-rw-r--r--src/ui.c3
7 files changed, 125 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 1445575..b4ed0a7 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ endif
PIANOBAR_DIR:=src
PIANOBAR_SRC:=\
${PIANOBAR_DIR}/main.c \
+ ${PIANOBAR_DIR}/debug.c \
${PIANOBAR_DIR}/player.c \
${PIANOBAR_DIR}/settings.c \
${PIANOBAR_DIR}/terminal.c \
diff --git a/src/config.h b/src/config.h
index 48a4cfe..4580f43 100644
--- a/src/config.h
+++ b/src/config.h
@@ -42,3 +42,10 @@
#define HAVE_AV_REGISTER_ALL
#endif
+#ifndef NDEBUG
+#define HAVE_DEBUGLOG
+#define debug(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define debug(...)
+#endif
+
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 0000000..95ca817
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,29 @@
+/*
+Copyright (c) 2008-2018
+ Lars-Dominik Braun <lars@6xq.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "debug.h"
+
+#ifdef HAVE_DEBUGLOG
+unsigned int debug = 0;
+#endif
+
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 0000000..e2e356b
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,64 @@
+/*
+Copyright (c) 2008-2018
+ Lars-Dominik Braun <lars@6xq.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "config.h"
+#include <stdbool.h>
+
+#ifdef HAVE_DEBUGLOG
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* bitfield */
+typedef enum {
+ DEBUG_NETWORK = 1,
+ DEBUG_AUDIO = 2,
+ DEBUG_UI = 4,
+} debugKind;
+
+extern unsigned int debug;
+
+inline static bool debugEnable () {
+ const char * const debugStr = getenv("PIANOBAR_DEBUG");
+ if (debugStr != NULL) {
+ debug = atoi (debugStr);
+ }
+ return debug;
+}
+
+__attribute__((format(printf, 2, 3)))
+inline static void debugPrint(debugKind kind, const char * const format, ...) {
+ if (debug & kind) {
+ va_list fmtargs;
+ va_start (fmtargs, format);
+ vfprintf (stderr, format, fmtargs);
+ va_end (fmtargs);
+ }
+}
+#else
+inline static bool debugEnable () {}
+#define debugPrint(...)
+#endif
+
diff --git a/src/main.c b/src/main.c
index 6388cde..de09fb7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -51,6 +51,7 @@ THE SOFTWARE.
#include <piano.h>
#include "main.h"
+#include "debug.h"
#include "terminal.h"
#include "ui.h"
#include "ui_dispatch.h"
@@ -401,6 +402,7 @@ sig_atomic_t *interrupted = NULL;
static void intHandler (int signal) {
if (interrupted != NULL) {
+ debugPrint(DEBUG_UI, "Received ^C\n");
*interrupted += 1;
}
}
@@ -417,6 +419,8 @@ static void BarMainSetupSigaction () {
int main (int argc, char **argv) {
static BarApp_t app;
+ debugEnable();
+
memset (&app, 0, sizeof (app));
/* save terminal attributes, before disabling echoing */
diff --git a/src/player.c b/src/player.c
index d73b718..b8eeead 100644
--- a/src/player.c
+++ b/src/player.c
@@ -41,6 +41,7 @@ THE SOFTWARE.
#include <fcntl.h>
#include <limits.h>
#include <assert.h>
+#include <inttypes.h>
#include <arpa/inet.h>
#include <sys/stat.h>
@@ -58,6 +59,7 @@ THE SOFTWARE.
#include <libavutil/frame.h>
#include "player.h"
+#include "debug.h"
#include "ui.h"
#include "ui_types.h"
@@ -421,6 +423,7 @@ static int play (player_t * const player) {
/* enter drain mode */
drainMode = DRAIN;
avcodec_send_packet (cctx, NULL);
+ debugPrint (DEBUG_AUDIO, "decoder entering drain mode after EOF\n");
} else if (pkt.stream_index != player->streamIdx) {
/* unused packet */
av_packet_unref (&pkt);
@@ -428,6 +431,8 @@ static int play (player_t * const player) {
} else if (ret < 0) {
/* error, abort */
/* mark the EOF, so that BarAoPlayThread can quit*/
+ debugPrint (DEBUG_AUDIO, "av_read_frame failed with code %i, sending "
+ "NULL frame\n", ret);
pthread_mutex_lock (&player->aoplayLock);
const int rt = av_buffersrc_add_frame (player->fabuf, NULL);
assert (rt == 0);
@@ -446,6 +451,7 @@ static int play (player_t * const player) {
/* done draining */
drainMode = DONE;
/* mark the EOF*/
+ debugPrint (DEBUG_AUDIO, "receive_frame got EOF, sending NULL frame\n");
pthread_mutex_lock (&player->aoplayLock);
const int rt = av_buffersrc_add_frame (player->fabuf, NULL);
assert (rt == 0);
@@ -471,10 +477,14 @@ static int play (player_t * const player) {
pthread_mutex_lock (&player->aoplayLock);
bufferHealth = timeBase * (double) (frame->pts - player->lastTimestamp);
if (bufferHealth > minBufferHealth) {
+ debugPrint (DEBUG_AUDIO, "decoding buffer filled health %"PRIi64" minHealth %"PRIi64"\n",
+ bufferHealth, minBufferHealth);
/* Buffer get healthy, resume */
pthread_cond_broadcast (&player->aoplayCond);
/* Buffer is healthy enough, wait */
pthread_cond_wait (&player->aoplayCond, &player->aoplayLock);
+ debugPrint (DEBUG_AUDIO, "ao play signalled it needs more data health %"PRIi64" minHealth %"PRIi64"\n",
+ bufferHealth, minBufferHealth);
}
pthread_mutex_unlock (&player->aoplayLock);
} while (bufferHealth > minBufferHealth);
@@ -483,6 +493,7 @@ static int play (player_t * const player) {
av_packet_unref (&pkt);
}
av_frame_free (&frame);
+ debugPrint (DEBUG_AUDIO, "decoder is done, waiting for ao player\n");
pthread_join (aoplaythread, NULL);
return ret;
@@ -558,9 +569,12 @@ void *BarAoPlayThread (void *data) {
if (ret == AVERROR_EOF || shouldQuit (player)) {
/* we are done here */
pthread_mutex_unlock (&player->aoplayLock);
+ debugPrint (DEBUG_AUDIO, "ao player got EOF, exiting\n");
break;
} else if (ret < 0) {
/* wait for more frames */
+ debugPrint (DEBUG_AUDIO, "ao player is waiting for more frames after code %i (%s)\n",
+ ret, av_err2str (ret));
pthread_cond_broadcast (&player->aoplayCond);
pthread_cond_wait (&player->aoplayCond, &player->aoplayLock);
pthread_mutex_unlock (&player->aoplayLock);
@@ -582,8 +596,10 @@ void *BarAoPlayThread (void *data) {
/* pausing */
if (player->doPause) {
do {
+ debugPrint (DEBUG_AUDIO, "ao player is paused\n");
pthread_cond_wait (&player->cond, &player->lock);
} while (player->doPause);
+ debugPrint (DEBUG_AUDIO, "ao player continues\n");
}
pthread_mutex_unlock (&player->lock);
@@ -599,6 +615,7 @@ void *BarAoPlayThread (void *data) {
av_frame_unref (filteredFrame);
}
av_frame_free (&filteredFrame);
+ debugPrint (DEBUG_AUDIO, "ao player is done\n");
return (void *) 0;
}
diff --git a/src/ui.c b/src/ui.c
index 6ccc2af..99b74c3 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -40,6 +40,7 @@ THE SOFTWARE.
#include <sys/wait.h>
#include "ui.h"
+#include "debug.h"
#include "ui_readline.h"
typedef int (*BarSortFunc_t) (const void *, const void *);
@@ -189,6 +190,7 @@ static CURLcode BarPianoHttpRequest (CURL * const http,
req->secure ? settings->rpcTlsPort : "80",
req->urlPath);
assert (ret >= 0 && ret <= (int) sizeof (url));
+ debugPrint (DEBUG_NETWORK, "← %s\n", url);
/* save the previous interrupt destination */
prevint = interrupted;
@@ -261,6 +263,7 @@ static CURLcode BarPianoHttpRequest (CURL * const http,
curl_slist_free_all (list);
req->responseData = buffer.data;
+ debugPrint (DEBUG_NETWORK, "→ %s\n", req->responseData);
interrupted = prevint;