diff --git a/audecode.c b/audecode.c
index e5269f9dfc6a74bc7e8869a8ab87ed184575c566..fae227a324475a7827ab5d493f8406afeb728843 100644
--- a/audecode.c
+++ b/audecode.c
@@ -426,7 +426,11 @@ void audecode_dump_metadata(audecode_t p) {
 audecode_metadata_iterator_t audecode_get_metadata(audecode_t p) {
   audecode_metadata_iterator_t mdi = (audecode_metadata_iterator_t)malloc(sizeof(struct audecode_metadata_iterator));
   mdi->p = p;
-  mdi->meta = p->fmt->metadata;
+  if (p->fmt->metadata && av_dict_count(p->fmt->metadata) > 0) {
+    mdi->meta = p->fmt->metadata;
+  } else {
+    mdi->meta = p->stream->metadata;
+  }
   mdi->entry = NULL;
   return mdi;
 }
diff --git a/test_decode.c b/test_decode.c
index 2142a5d14d536571b5afc1c8bedbd1729b3ed541..f3d06d92ef0b8b2b969036f356a7094718b3a6b9 100644
--- a/test_decode.c
+++ b/test_decode.c
@@ -11,8 +11,6 @@
 #include "audecode.h"
 #include "test_lib.h"
 
-static char input_file[4096];
-
 void decode_input(int sample_rate, int channels, int bytes_per_sample, uint8_t **obuf, int *osz) {
   audecode_t p;
   struct fdctx ctx;
@@ -23,10 +21,10 @@ void decode_input(int sample_rate, int channels, int bytes_per_sample, uint8_t *
   *osz = 0;
 
   read_bytes = 0;
-  ctx.fd = open(input_file, O_RDONLY);
+  ctx.fd = open(path_of(TEST_INPUT), O_RDONLY);
   r = audecode_new(&p, 4096, &my_read_cb, (void *)&ctx);
   if (r < 0) {
-    die(r);
+    die("audecode_new", r);
   }
 
   audecode_set_output_params(p, sample_rate, channels, bytes_per_sample);
@@ -186,35 +184,36 @@ int test_codec_params() {
   const char *codec = NULL;
   int bit_rate = 0;
   struct fdctx ctx;
-  int r;
+  int r, ret = 0;
 
-  ctx.fd = open(input_file, O_RDONLY);
+  ctx.fd = open(path_of(TEST_INPUT), O_RDONLY);
   r = audecode_new(&p, 4096, &my_read_cb, (void *)&ctx);
   if (r < 0) {
-    die(r);
+    die("audecode_new", r);
   }
 
   audecode_get_input_codec_params(p, &codec, &bit_rate);
   if (codec == NULL) {
     fprintf(stdout, "ERROR: 'codec' is empty\n");
-    return 1;
+    ret = 1;
   }
   if (strcmp(codec, "flac") != 0) {
     fprintf(stdout, "ERROR: 'codec' is '%s', not 'flac'\n", codec);
-    return 1;
+    ret = 1;
   }
   if (bit_rate != 0) {
     fprintf(stdout, "ERROR: 'bit_rate' is not empty (%d)\n", bit_rate);
-    return 1;
+    ret = 1;
   }
-  return 0;
+
+  audecode_close(p);
+
+  return ret;
 }
 
 int main(int argc, char **argv) {
   int errors = 0;
 
-  sprintf(input_file, "%s/%s", getenv("srcdir"), TEST_INPUT);
-
   audecode_init();
 
   fprintf(stdout, "test_decode\n");
diff --git a/test_lib.h b/test_lib.h
index af7987346eec535c4fffff52e878df201758cd9b..66424381e4abbf8476af809b9ae92cc9821bdd0d 100644
--- a/test_lib.h
+++ b/test_lib.h
@@ -7,6 +7,8 @@
 #define TEST_NUM_SAMPLES 138526
 #define TEST_INPUT_SIZE 656450
 
+#include <string.h>
+
 static int read_bytes;
 
 struct fdctx {
@@ -21,14 +23,21 @@ static int my_read_cb(void *opaque, uint8_t *buf, int buf_size) {
   }
 }
 
-void die(int error) {
+void die(const char *tag, int error) {
   char errbuf[256];
   audecode_strerror(error, errbuf, sizeof(errbuf));
-  fprintf(stderr, "TEST ERROR: %s\n", errbuf);
+  fprintf(stderr, "TEST ERROR: %s: %s\n", tag, errbuf);
   exit(1);
 }
 
-void die_msg(char *s) {
+void die_msg(const char *s) {
   fprintf(stderr, "TEST ERROR: %s\n", s);
   exit(1);
 }
+
+char *path_of(const char *base) {
+  char *srcdir = getenv("srcdir");
+  char *out = (char *)malloc(2 + strlen(srcdir) + strlen(base));
+  sprintf(out, "%s/%s", srcdir, base);
+  return out;
+}
diff --git a/test_meta.c b/test_meta.c
index b82102c457ba95efe001480d6321db2f2147401c..fe8ab0402e7f5a29a62f51c79e7599dc1d9abacb 100644
--- a/test_meta.c
+++ b/test_meta.c
@@ -17,10 +17,10 @@ int test_read_artist(char *input_file) {
   struct fdctx ctx;
   int r, count = 0;
 
-  ctx.fd = open(input_file, O_RDONLY);
+  ctx.fd = open(path_of(input_file), O_RDONLY);
   r = audecode_new(&p, 4096, &my_read_cb, (void *)&ctx);
   if (r < 0) {
-    die(r);
+    die("audecode_new", r);
   }
 
   mdi = audecode_get_metadata(p);
@@ -45,11 +45,56 @@ int test_read_artist(char *input_file) {
     die_msg("read too much metadata");
   }
 
+  audecode_close(p);
+
+  return 0;
+}
+
+int test_read_any_meta(char *input_file) {
+  audecode_t p;
+  audecode_metadata_iterator_t mdi;
+  char *key, *value;
+  struct fdctx ctx;
+  int r, count = 0;
+
+  ctx.fd = open(path_of(input_file), O_RDONLY);
+  r = audecode_new(&p, 4096, &my_read_cb, (void *)&ctx);
+  if (r < 0) {
+    die("audecode_new", r);
+  }
+
+  mdi = audecode_get_metadata(p);
+  if (mdi == NULL) {
+    fprintf(stderr, "ERROR: audecode_get_metadata(%s) returned NULL\n", input_file);
+    return 1;
+  }
+
+  while (0 == audecode_metadata_next(mdi, &key, &value)) {
+    fprintf(stderr, "md: %s = %s\n", key, value);
+    count++;
+  }
+  if (count == 0) {
+    fprintf(stdout, "ERROR: found no metadata in %s\n", input_file);
+    audecode_dump_metadata(p);
+    return 1;
+  }
+
+  audecode_close(p);
+
   return 0;
 }
 
 int main(int argc, char **argv) {
+  int errors = 0;
+
   audecode_init();
 
-  return test_read_artist(TEST_INPUT);
+  fprintf(stdout, "test_read_artist\n");
+  errors += test_read_artist(TEST_INPUT);
+  fprintf(stdout, "test_read_any_meta\n");
+  errors += test_read_any_meta("testdata/meta1.mp3");
+  errors += test_read_any_meta("testdata/meta1.flac");
+  errors += test_read_any_meta("testdata/meta1.ogg");
+
+  return (errors > 0) ? 1 : 0;
 }
diff --git a/testdata/meta1.flac b/testdata/meta1.flac
new file mode 100644
index 0000000000000000000000000000000000000000..a1cc8098adf6d9e69e38f9f1751b1197b77001a6
Binary files /dev/null and b/testdata/meta1.flac differ
diff --git a/testdata/meta1.mp3 b/testdata/meta1.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..5faa15fcf9c8240d69b43365712afcf80391aeee
Binary files /dev/null and b/testdata/meta1.mp3 differ
diff --git a/testdata/meta1.ogg b/testdata/meta1.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..9e8dd4a26c9d68c8a85b8d7a6f0dad5949c0d737
Binary files /dev/null and b/testdata/meta1.ogg differ