1/*
2 * Copyright (C) 2009-2011 Julien BLACHE <jb@jblache.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <errno.h>
28
29#ifdef HAVE_STDINT_H
30#include <stdint.h>
31#endif
32
33#include <libavcodec/avcodec.h>
34#include <libavformat/avformat.h>
35
36#include "logger.h"
37#include "filescanner.h"
38#include "misc.h"
39
40
41/* Legacy format-specific scanners */
42extern int scan_get_wmainfo(char *filename, struct media_file_info *pmp3);
43#ifdef FLAC
44extern int scan_get_flacinfo(char *filename, struct media_file_info *pmp3);
45#endif
46#ifdef MUSEPACK
47extern int scan_get_mpcinfo(char *filename, struct media_file_info *pmp3);
48#endif
49
50
51/* Mapping between the metadata name(s) and the offset
52 * of the equivalent metadata field in struct media_file_info */
53struct metadata_map {
54  char *key;
55  int as_int;
56  size_t offset;
57  int (*handler_function)(struct media_file_info *, char *);
58};
59
60static int
61parse_slash_separated_ints(char *string, uint32_t *firstval, uint32_t *secondval)
62{
63  int numvals = 0;
64  char *ptr;
65
66  ptr = strchr(string, '/');
67  if (ptr)
68    {
69      *ptr = '\0';
70      if (safe_atou32(ptr + 1, secondval) == 0)
71        numvals++;
72    }
73
74  if (safe_atou32(string, firstval) == 0)
75    numvals++;
76
77  return numvals;
78}
79
80static int
81parse_track(struct media_file_info *mfi, char *track_string)
82{
83  uint32_t *track = (uint32_t *) ((char *) mfi + mfi_offsetof(track));
84  uint32_t *total_tracks = (uint32_t *) ((char *) mfi + mfi_offsetof(total_tracks));
85
86  return parse_slash_separated_ints(track_string, track, total_tracks);
87}
88
89static int
90parse_disc(struct media_file_info *mfi, char *disc_string)
91{
92  uint32_t *disc = (uint32_t *) ((char *) mfi + mfi_offsetof(disc));
93  uint32_t *total_discs = (uint32_t *) ((char *) mfi + mfi_offsetof(total_discs));
94
95  return parse_slash_separated_ints(disc_string, disc, total_discs);
96}
97
98/* Lookup is case-insensitive, first occurrence takes precedence */
99static const struct metadata_map md_map_generic[] =
100  {
101    { "title",        0, mfi_offsetof(title),              NULL },
102    { "artist",       0, mfi_offsetof(artist),             NULL },
103    { "author",       0, mfi_offsetof(artist),             NULL },
104    { "album_artist", 0, mfi_offsetof(album_artist),       NULL },
105    { "album",        0, mfi_offsetof(album),              NULL },
106    { "genre",        0, mfi_offsetof(genre),              NULL },
107    { "composer",     0, mfi_offsetof(composer),           NULL },
108    { "grouping",     0, mfi_offsetof(grouping),           NULL },
109    { "orchestra",    0, mfi_offsetof(orchestra),          NULL },
110    { "conductor",    0, mfi_offsetof(conductor),          NULL },
111    { "comment",      0, mfi_offsetof(comment),            NULL },
112    { "description",  0, mfi_offsetof(comment),            NULL },
113    { "track",        1, mfi_offsetof(track),              parse_track },
114    { "disc",         1, mfi_offsetof(disc),               parse_disc },
115    { "year",         1, mfi_offsetof(year),               NULL },
116    { "date",         1, mfi_offsetof(year),               NULL },
117    { "title-sort",   0, mfi_offsetof(title_sort),         NULL },
118    { "artist-sort",  0, mfi_offsetof(artist_sort),        NULL },
119    { "album-sort",   0, mfi_offsetof(album_sort),         NULL },
120
121    { NULL,           0, 0,                                NULL }
122  };
123
124static const struct metadata_map md_map_tv[] =
125  {
126    { "stik",         1, mfi_offsetof(media_kind),         NULL },
127    { "show",         0, mfi_offsetof(tv_series_name),     NULL },
128    { "episode_id",   0, mfi_offsetof(tv_episode_num_str), NULL },
129    { "network",      0, mfi_offsetof(tv_network_name),    NULL },
130    { "episode_sort", 1, mfi_offsetof(tv_episode_sort),    NULL },
131    { "season_number",1, mfi_offsetof(tv_season_num),      NULL },
132
133    { NULL,           0, 0,                                NULL }
134  };
135
136/* NOTE about VORBIS comments:
137 *  Only a small set of VORBIS comment fields are officially designated. Most
138 *  common tags are at best de facto standards. Currently, metadata conversion
139 *  functionality in ffmpeg only adds support for a couple of tags. Specifically,
140 *  ALBUMARTIST and TRACKNUMBER are handled as of Feb 1, 2010 (rev 21587). Tags
141 *  with names that already match the generic ffmpeg scheme--TITLE and ARTIST,
142 *  for example--are of course handled. The rest of these tags are reported to
143 *  have been used by various programs in the wild.
144 */
145static const struct metadata_map md_map_vorbis[] =
146  {
147    { "albumartist",  0, mfi_offsetof(album_artist),      NULL },
148    { "album artist", 0, mfi_offsetof(album_artist),      NULL },
149    { "tracknumber",  1, mfi_offsetof(track),             NULL },
150    { "tracktotal",   1, mfi_offsetof(total_tracks),      NULL },
151    { "totaltracks",  1, mfi_offsetof(total_tracks),      NULL },
152    { "discnumber",   1, mfi_offsetof(disc),              NULL },
153    { "disctotal",    1, mfi_offsetof(total_discs),       NULL },
154    { "totaldiscs",   1, mfi_offsetof(total_discs),       NULL },
155
156    { NULL,           0, 0,                               NULL }
157  };
158
159/* NOTE about ID3 tag names:
160 *  metadata conversion for ID3v2 tags was added in ffmpeg in september 2009
161 *  (rev 20073) for ID3v2.3; support for ID3v2.2 tag names was added in december
162 *  2009 (rev 20839).
163 *
164 * ID3v2.x tags will be removed from the map once a version of ffmpeg containing
165 * the changes listed above will be generally available. The more entries in the
166 * map, the slower the filescanner gets.
167 */
168static const struct metadata_map md_map_id3[] =
169  {
170    { "TT2",                 0, mfi_offsetof(title),                 NULL },              /* ID3v2.2 */
171    { "TIT2",                0, mfi_offsetof(title),                 NULL },              /* ID3v2.3 */
172    { "TP1",                 0, mfi_offsetof(artist),                NULL },              /* ID3v2.2 */
173    { "TPE1",                0, mfi_offsetof(artist),                NULL },              /* ID3v2.3 */
174    { "TP2",                 0, mfi_offsetof(album_artist),          NULL },              /* ID3v2.2 */
175    { "TPE2",                0, mfi_offsetof(album_artist),          NULL },              /* ID3v2.3 */
176    { "TAL",                 0, mfi_offsetof(album),                 NULL },              /* ID3v2.2 */
177    { "TALB",                0, mfi_offsetof(album),                 NULL },              /* ID3v2.3 */
178    { "TCO",                 0, mfi_offsetof(genre),                 NULL },              /* ID3v2.2 */
179    { "TCON",                0, mfi_offsetof(genre),                 NULL },              /* ID3v2.3 */
180    { "TCM",                 0, mfi_offsetof(composer),              NULL },              /* ID3v2.2 */
181    { "TCOM",                0, mfi_offsetof(composer),              NULL },              /* ID3v2.3 */
182    { "TRK",                 1, mfi_offsetof(track),                 parse_track },       /* ID3v2.2 */
183    { "TRCK",                1, mfi_offsetof(track),                 parse_track },       /* ID3v2.3 */
184    { "TPA",                 1, mfi_offsetof(disc),                  parse_disc },        /* ID3v2.2 */
185    { "TPOS",                1, mfi_offsetof(disc),                  parse_disc },        /* ID3v2.3 */
186    { "TYE",                 1, mfi_offsetof(year),                  NULL },              /* ID3v2.2 */
187    { "TYER",                1, mfi_offsetof(year),                  NULL },              /* ID3v2.3 */
188    { "TDRC",                1, mfi_offsetof(year),                  NULL },              /* ID3v2.4 */
189    { "TSOA",                0, mfi_offsetof(album_sort),            NULL },              /* ID3v2.4 */
190    { "XSOA",                0, mfi_offsetof(album_sort),            NULL },              /* ID3v2.3 */
191    { "TSOP",                0, mfi_offsetof(artist_sort),           NULL },              /* ID3v2.4 */
192    { "XSOP",                0, mfi_offsetof(artist_sort),           NULL },              /* ID3v2.3 */
193    { "TSOT",                0, mfi_offsetof(title_sort),            NULL },              /* ID3v2.4 */
194    { "XSOT",                0, mfi_offsetof(title_sort),            NULL },              /* ID3v2.3 */
195    { "TS2",                 0, mfi_offsetof(album_artist_sort),     NULL },              /* ID3v2.2 */
196    { "TSO2",                0, mfi_offsetof(album_artist_sort),     NULL },              /* ID3v2.3 */
197    { "ALBUMARTISTSORT",     0, mfi_offsetof(album_artist_sort),     NULL },              /* ID3v2.x */
198    { "TSC",                 0, mfi_offsetof(composer_sort),         NULL },              /* ID3v2.2 */
199    { "TSOC",                0, mfi_offsetof(composer_sort),         NULL },              /* ID3v2.3 */
200
201    { NULL,                  0, 0,                                   NULL }
202  };
203
204
205static int
206#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 5)
207extract_metadata_core(struct media_file_info *mfi, AVDictionary *md, const struct metadata_map *md_map)
208#else
209extract_metadata_core(struct media_file_info *mfi, AVMetadata *md, const struct metadata_map *md_map)
210#endif
211{
212#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 5)
213  AVDictionaryEntry *mdt;
214#else
215  AVMetadataTag *mdt;
216#endif
217  char **strval;
218  uint32_t *intval;
219  int mdcount;
220  int i;
221  int ret;
222
223#if 0
224  /* Dump all the metadata reported by ffmpeg */
225  mdt = NULL;
226#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 5)
227  while ((mdt = av_dict_get(md, "", mdt, AV_DICT_IGNORE_SUFFIX)) != NULL)
228#else
229  while ((mdt = av_metadata_get(md, "", mdt, AV_METADATA_IGNORE_SUFFIX)) != NULL)
230#endif
231    fprintf(stderr, " -> %s = %s\n", mdt->key, mdt->value);
232#endif
233
234  mdcount = 0;
235
236  /* Extract actual metadata */
237  for (i = 0; md_map[i].key != NULL; i++)
238    {
239#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 5)
240      mdt = av_dict_get(md, md_map[i].key, NULL, 0);
241#else
242      mdt = av_metadata_get(md, md_map[i].key, NULL, 0);
243#endif
244      if (mdt == NULL)
245	continue;
246
247      if ((mdt->value == NULL) || (strlen(mdt->value) == 0))
248	continue;
249
250      if (md_map[i].handler_function)
251	{
252	  mdcount += md_map[i].handler_function(mfi, mdt->value);
253	  continue;
254	}
255
256      mdcount++;
257
258      if (!md_map[i].as_int)
259	{
260	  strval = (char **) ((char *) mfi + md_map[i].offset);
261
262	  if (*strval == NULL)
263	    *strval = strdup(mdt->value);
264	}
265      else
266	{
267	  intval = (uint32_t *) ((char *) mfi + md_map[i].offset);
268
269	  if (*intval == 0)
270	    {
271	      ret = safe_atou32(mdt->value, intval);
272	      if (ret < 0)
273		continue;
274	    }
275	}
276    }
277
278  return mdcount;
279}
280
281static int
282extract_metadata(struct media_file_info *mfi, AVFormatContext *ctx, AVStream *audio_stream, AVStream *video_stream, const struct metadata_map *md_map)
283{
284  int mdcount;
285  int ret;
286
287  mdcount = 0;
288
289  if (ctx->metadata)
290    {
291      ret = extract_metadata_core(mfi, ctx->metadata, md_map);
292      mdcount += ret;
293
294      DPRINTF(E_DBG, L_SCAN, "Picked up %d tags from file metadata\n", ret);
295    }
296
297  if (audio_stream->metadata)
298    {
299      ret = extract_metadata_core(mfi, audio_stream->metadata, md_map);
300      mdcount += ret;
301
302      DPRINTF(E_DBG, L_SCAN, "Picked up %d tags from audio stream metadata\n", ret);
303    }
304
305  if (video_stream && video_stream->metadata)
306    {
307      ret = extract_metadata_core(mfi, video_stream->metadata, md_map);
308      mdcount += ret;
309
310      DPRINTF(E_DBG, L_SCAN, "Picked up %d tags from video stream metadata\n", ret);
311    }
312
313  return mdcount;
314}
315
316int
317scan_metadata_ffmpeg(char *file, struct media_file_info *mfi)
318{
319  AVFormatContext *ctx;
320  const struct metadata_map *extra_md_map;
321  enum CodecID codec_id;
322  enum CodecID video_codec_id;
323  enum CodecID audio_codec_id;
324  AVStream *video_stream;
325  AVStream *audio_stream;
326  int mdcount;
327  int i;
328  int ret;
329
330  ctx = NULL;
331
332#if LIBAVFORMAT_VERSION_MAJOR >= 53 || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR >= 3)
333  ret = avformat_open_input(&ctx, file, NULL, NULL);
334#else
335  ret = av_open_input_file(&ctx, file, NULL, 0, NULL);
336#endif
337  if (ret != 0)
338    {
339      DPRINTF(E_WARN, L_SCAN, "Cannot open media file '%s': %s\n", file, strerror(AVUNERROR(ret)));
340
341      return -1;
342    }
343
344  ret = avformat_find_stream_info(ctx,NULL);
345  if (ret < 0)
346    {
347      DPRINTF(E_WARN, L_SCAN, "Cannot get stream info: %s\n", strerror(AVUNERROR(ret)));
348
349      av_close_input_file(ctx);
350      return -1;
351    }
352
353#if 0
354  /* Dump input format as determined by ffmpeg */
355# if LIBAVFORMAT_VERSION_MAJOR >= 52 || (LIBAVFORMAT_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 101)
356  av_dump_format(ctx, 0, file, 0);
357# else
358  dump_format(ctx, 0, file, FALSE);
359# endif
360#endif
361
362  DPRINTF(E_DBG, L_SCAN, "File has %d streams\n", ctx->nb_streams);
363
364  /* Extract codec IDs, check for video */
365  video_codec_id = CODEC_ID_NONE;
366  video_stream = NULL;
367
368  audio_codec_id = CODEC_ID_NONE;
369  audio_stream = NULL;
370
371  for (i = 0; i < ctx->nb_streams; i++)
372    {
373      switch (ctx->streams[i]->codec->codec_type)
374	{
375#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 64)
376	  case AVMEDIA_TYPE_VIDEO:
377#else
378	  case CODEC_TYPE_VIDEO:
379#endif
380//	    if (!video_stream && !(ctx->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC))
381	    if (!video_stream)
382	      {
383		DPRINTF(E_DBG, L_SCAN, "File has video (stream %d)\n", i);
384
385		mfi->has_video = 1;
386		video_stream = ctx->streams[i];
387		video_codec_id = video_stream->codec->codec_id;
388	      }
389	    break;
390
391#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 64)
392	  case AVMEDIA_TYPE_AUDIO:
393#else
394	  case CODEC_TYPE_AUDIO:
395#endif
396	    if (!audio_stream)
397	      {
398		audio_stream = ctx->streams[i];
399		audio_codec_id = audio_stream->codec->codec_id;
400	      }
401	    break;
402
403	  default:
404	    break;
405	}
406    }
407
408  if (audio_codec_id == CODEC_ID_NONE)
409    {
410      DPRINTF(E_DBG, L_SCAN, "File has no audio streams, discarding\n");
411
412      av_close_input_file(ctx);
413      return -1;
414    }
415
416  /* Common media information */
417  if (ctx->duration > 0)
418    mfi->song_length = ctx->duration / (AV_TIME_BASE / 1000); /* ms */
419
420  if (ctx->bit_rate > 0)
421    mfi->bitrate = ctx->bit_rate / 1000;
422  else if (ctx->duration > AV_TIME_BASE) /* guesstimate */
423    mfi->bitrate = ((mfi->file_size * 8) / (ctx->duration / AV_TIME_BASE)) / 1000;
424
425  DPRINTF(E_DBG, L_SCAN, "Duration %d ms, bitrate %d kbps\n", mfi->song_length, mfi->bitrate);
426
427  /* Get some more information on the audio stream */
428  if (audio_stream)
429    {
430      if (audio_stream->codec->sample_rate != 0)
431	mfi->samplerate = audio_stream->codec->sample_rate;
432
433      /* Try sample format first */
434#if LIBAVUTIL_VERSION_MAJOR >= 51 || (LIBAVUTIL_VERSION_MAJOR == 51 && LIBAVUTIL_VERSION_MINOR >= 4)
435      mfi->bits_per_sample = 8 * av_get_bytes_per_sample(audio_stream->codec->sample_fmt);
436#elif LIBAVCODEC_VERSION_MAJOR >= 53
437      mfi->bits_per_sample = av_get_bits_per_sample_fmt(audio_stream->codec->sample_fmt);
438#else
439      mfi->bits_per_sample = av_get_bits_per_sample_format(audio_stream->codec->sample_fmt);
440#endif
441      if (mfi->bits_per_sample == 0)
442	{
443	  /* Try codec */
444	  mfi->bits_per_sample = av_get_bits_per_sample(audio_codec_id);
445	}
446
447      DPRINTF(E_DBG, L_SCAN, "samplerate %d, bps %d\n", mfi->samplerate, mfi->bits_per_sample);
448    }
449
450  /* Check codec */
451  extra_md_map = NULL;
452  codec_id = (mfi->has_video) ? video_codec_id : audio_codec_id;
453  switch (codec_id)
454    {
455      case CODEC_ID_AAC:
456	DPRINTF(E_DBG, L_SCAN, "AAC\n");
457	mfi->type = strdup("m4a");
458	mfi->codectype = strdup("mp4a");
459	mfi->description = strdup("AAC audio file");
460	break;
461
462      case CODEC_ID_ALAC:
463	DPRINTF(E_DBG, L_SCAN, "ALAC\n");
464	mfi->type = strdup("m4a");
465	mfi->codectype = strdup("alac");
466	mfi->description = strdup("AAC audio file");
467	break;
468
469      case CODEC_ID_FLAC:
470	DPRINTF(E_DBG, L_SCAN, "FLAC\n");
471	mfi->type = strdup("flac");
472	mfi->codectype = strdup("flac");
473	mfi->description = strdup("FLAC audio file");
474
475	extra_md_map = md_map_vorbis;
476	break;
477
478      case CODEC_ID_MUSEPACK7:
479      case CODEC_ID_MUSEPACK8:
480	DPRINTF(E_DBG, L_SCAN, "Musepack\n");
481	mfi->type = strdup("mpc");
482	mfi->codectype = strdup("mpc");
483	mfi->description = strdup("Musepack audio file");
484	break;
485
486      case CODEC_ID_MPEG4: /* Video */
487      case CODEC_ID_H264:
488	DPRINTF(E_DBG, L_SCAN, "MPEG4 video\n");
489	mfi->type = strdup("m4v");
490	mfi->codectype = strdup("mp4v");
491	mfi->description = strdup("MPEG-4 video file");
492
493	extra_md_map = md_map_tv;
494	break;
495
496      case CODEC_ID_MP3:
497	DPRINTF(E_DBG, L_SCAN, "MP3\n");
498	mfi->type = strdup("mp3");
499	mfi->codectype = strdup("mpeg");
500	mfi->description = strdup("MPEG audio file");
501
502	extra_md_map = md_map_id3;
503	break;
504
505      case CODEC_ID_VORBIS:
506	DPRINTF(E_DBG, L_SCAN, "VORBIS\n");
507	mfi->type = strdup("ogg");
508	mfi->codectype = strdup("ogg");
509	mfi->description = strdup("Ogg Vorbis audio file");
510
511	extra_md_map = md_map_vorbis;
512	break;
513
514      case CODEC_ID_WMAVOICE:
515	DPRINTF(E_DBG, L_SCAN, "WMA Voice\n");
516	mfi->type = strdup("wma");
517	mfi->codectype = strdup("wmav");
518	mfi->description = strdup("WMA audio file");
519	break;
520
521      case CODEC_ID_WMAPRO:
522	DPRINTF(E_DBG, L_SCAN, "WMA Pro\n");
523	mfi->type = strdup("wmap");
524	mfi->codectype = strdup("wma");
525	mfi->description = strdup("WMA audio file");
526	break;
527
528      case CODEC_ID_WMALOSSLESS:
529	DPRINTF(E_DBG, L_SCAN, "WMA Lossless\n");
530	mfi->type = strdup("wma");
531	mfi->codectype = strdup("wmal");
532	mfi->description = strdup("WMA audio file");
533	break;
534
535      case CODEC_ID_PCM_S16LE ... CODEC_ID_PCM_F64LE:
536	if (strcmp(ctx->iformat->name, "aiff") == 0)
537	  {
538	    DPRINTF(E_DBG, L_SCAN, "AIFF\n");
539	    mfi->type = strdup("aif");
540	    mfi->codectype = strdup("aif");
541	    mfi->description = strdup("AIFF audio file");
542	    break;
543	  }
544	else if (strcmp(ctx->iformat->name, "wav") == 0)
545	  {
546	    DPRINTF(E_DBG, L_SCAN, "WAV\n");
547	    mfi->type = strdup("wav");
548	    mfi->codectype = strdup("wav");
549	    mfi->description = strdup("WAV audio file");
550	    break;
551	  }
552	/* WARNING: will fallthrough to default case, don't move */
553	/* FALLTHROUGH */
554
555      default:
556	DPRINTF(E_DBG, L_SCAN, "Unknown codec 0x%x (video: %s), format %s (%s)\n",
557		codec_id, (mfi->has_video) ? "yes" : "no", ctx->iformat->name, ctx->iformat->long_name);
558	mfi->type = strdup("unkn");
559	mfi->codectype = strdup("unkn");
560	if (mfi->has_video)
561	  {
562	    mfi->description = strdup("Unknown video file format");
563	    extra_md_map = md_map_tv;
564	  }
565	else
566	  mfi->description = strdup("Unknown audio file format");
567	break;
568    }
569
570  mdcount = 0;
571
572  if ((!ctx->metadata) && (!audio_stream->metadata)
573      && (video_stream && !video_stream->metadata))
574    {
575      DPRINTF(E_WARN, L_SCAN, "ffmpeg reports no metadata\n");
576
577      goto skip_extract;
578    }
579
580  if (extra_md_map)
581    {
582      ret = extract_metadata(mfi, ctx, audio_stream, video_stream, extra_md_map);
583      mdcount += ret;
584
585      DPRINTF(E_DBG, L_SCAN, "Picked up %d tags with extra md_map\n", ret);
586    }
587
588#if LIBAVFORMAT_VERSION_MAJOR < 53
589  av_metadata_conv(ctx, NULL, ctx->iformat->metadata_conv);
590#endif
591
592  ret = extract_metadata(mfi, ctx, audio_stream, video_stream, md_map_generic);
593  mdcount += ret;
594
595  DPRINTF(E_DBG, L_SCAN, "Picked up %d tags with generic md_map, %d tags total\n", ret, mdcount);
596
597  /* fix up TV metadata */
598  if (mfi->media_kind == 10)
599    {
600      /* I have no idea why this is, but iTunes reports a media kind of 64 for stik==10 (?!) */
601      mfi->media_kind = 64;
602    }
603  /* Unspecified video files are "Movies", media_kind 2 */
604  else if (mfi->has_video == 1)
605    {
606      mfi->media_kind = 2;
607    }
608
609 skip_extract:
610  if (mdcount == 0)
611    {
612      /* ffmpeg doesn't support FLAC nor Musepack metadata,
613       * and is buggy for some WMA variants, so fall back to the
614       * legacy format-specific parsers until it gets fixed */
615      if ((codec_id == CODEC_ID_WMAPRO)
616	  || (codec_id == CODEC_ID_WMAVOICE)
617	  || (codec_id == CODEC_ID_WMALOSSLESS))
618	{
619	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy WMA scanner\n");
620
621	  av_close_input_file(ctx);
622	  return (scan_get_wmainfo(file, mfi) ? 0 : -1);
623	}
624#ifdef FLAC
625      else if (codec_id == CODEC_ID_FLAC)
626	{
627	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy FLAC scanner\n");
628
629	  av_close_input_file(ctx);
630	  return (scan_get_flacinfo(file, mfi) ? 0 : -1);
631	}
632#endif /* FLAC */
633#ifdef MUSEPACK
634      else if ((codec_id == CODEC_ID_MUSEPACK7)
635	       || (codec_id == CODEC_ID_MUSEPACK8))
636	{
637	  DPRINTF(E_WARN, L_SCAN, "Falling back to legacy Musepack scanner\n");
638
639	  av_close_input_file(ctx);
640	  return (scan_get_mpcinfo(file, mfi) ? 0 : -1);
641	}
642#endif /* MUSEPACK */
643      else
644	DPRINTF(E_WARN, L_SCAN, "Could not extract any metadata\n");
645    }
646
647  /* Just in case there's no title set ... */
648  if (mfi->title == NULL)
649    mfi->title = strdup(mfi->fname);
650
651  /* All done */
652  av_close_input_file(ctx);
653
654  return 0;
655}
656