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