Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2000, 2001 Fabrice Bellard | ||
3 | * | ||
4 | * This file is part of FFmpeg. | ||
5 | * | ||
6 | * FFmpeg is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Lesser General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2.1 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * FFmpeg is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with FFmpeg; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | #include "libavutil/mem.h" | ||
22 | #include "asf.h" | ||
23 | #include "demux.h" | ||
24 | #include "id3v2.h" | ||
25 | #include "internal.h" | ||
26 | |||
27 | /* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */ | ||
28 | const AVMetadataConv ff_asf_metadata_conv[] = { | ||
29 | { "WM/AlbumArtist", "album_artist" }, | ||
30 | { "WM/AlbumTitle", "album" }, | ||
31 | { "Author", "artist" }, | ||
32 | { "Description", "comment" }, | ||
33 | { "WM/Composer", "composer" }, | ||
34 | { "WM/EncodedBy", "encoded_by" }, | ||
35 | { "WM/EncodingSettings", "encoder" }, | ||
36 | { "WM/Genre", "genre" }, | ||
37 | { "WM/Language", "language" }, | ||
38 | { "WM/OriginalFilename", "filename" }, | ||
39 | { "WM/PartOfSet", "disc" }, | ||
40 | { "WM/Publisher", "publisher" }, | ||
41 | { "WM/Tool", "encoder" }, | ||
42 | { "WM/TrackNumber", "track" }, | ||
43 | { "WM/MediaStationCallSign", "service_provider" }, | ||
44 | { "WM/MediaStationName", "service_name" }, | ||
45 | // { "Year" , "date" }, TODO: conversion year<->date | ||
46 | { 0 } | ||
47 | }; | ||
48 | |||
49 | /* MSDN claims that this should be "compatible with the ID3 frame, APIC", | ||
50 | * but in reality this is only loosely similar */ | ||
51 | 3 | static int asf_read_picture(AVFormatContext *s, int len) | |
52 | { | ||
53 | 3 | const CodecMime *mime = ff_id3v2_mime_tags; | |
54 | 3 | enum AVCodecID id = AV_CODEC_ID_NONE; | |
55 | char mimetype[64]; | ||
56 | 3 | uint8_t *desc = NULL; | |
57 | 3 | AVStream *st = NULL; | |
58 | int ret, type, picsize, desc_len; | ||
59 | |||
60 | /* type + picsize + mime + desc */ | ||
61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (len < 1 + 4 + 2 + 2) { |
62 | ✗ | av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len); | |
63 | ✗ | return AVERROR_INVALIDDATA; | |
64 | } | ||
65 | |||
66 | /* picture type */ | ||
67 | 3 | type = avio_r8(s->pb); | |
68 | 3 | len--; | |
69 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) { |
70 | ✗ | av_log(s, AV_LOG_WARNING, "Unknown attached picture type: %d.\n", type); | |
71 | ✗ | type = 0; | |
72 | } | ||
73 | |||
74 | /* picture data size */ | ||
75 | 3 | picsize = avio_rl32(s->pb); | |
76 | 3 | len -= 4; | |
77 | |||
78 | /* picture MIME type */ | ||
79 | 3 | len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype)); | |
80 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | while (mime->id != AV_CODEC_ID_NONE) { |
81 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { |
82 | 3 | id = mime->id; | |
83 | 3 | break; | |
84 | } | ||
85 | 3 | mime++; | |
86 | } | ||
87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (id == AV_CODEC_ID_NONE) { |
88 | ✗ | av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", | |
89 | mimetype); | ||
90 | ✗ | return 0; | |
91 | } | ||
92 | |||
93 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | if (picsize >= len || ((int64_t)len - picsize) * 2 + 1 > INT_MAX) { |
94 | ✗ | av_log(s, AV_LOG_ERROR, "Invalid attached picture data size: %d (len = %d).\n", | |
95 | picsize, len); | ||
96 | ✗ | return AVERROR_INVALIDDATA; | |
97 | } | ||
98 | |||
99 | /* picture description */ | ||
100 | 3 | desc_len = (len - picsize) * 2 + 1; | |
101 | 3 | desc = av_malloc(desc_len); | |
102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!desc) |
103 | ✗ | return AVERROR(ENOMEM); | |
104 | 3 | len -= avio_get_str16le(s->pb, len - picsize, desc, desc_len); | |
105 | |||
106 | 3 | ret = ff_add_attached_pic(s, NULL, s->pb, NULL, picsize); | |
107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (ret < 0) |
108 | ✗ | goto fail; | |
109 | 3 | st = s->streams[s->nb_streams - 1]; | |
110 | |||
111 | 3 | st->codecpar->codec_id = id; | |
112 | |||
113 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if (*desc) { |
114 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL) < 0) |
115 | ✗ | av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); | |
116 | } else | ||
117 | 1 | av_freep(&desc); | |
118 | |||
119 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | if (av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0) < 0) |
120 | ✗ | av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); | |
121 | |||
122 | 3 | return 0; | |
123 | |||
124 | ✗ | fail: | |
125 | ✗ | av_freep(&desc); | |
126 | ✗ | return ret; | |
127 | } | ||
128 | |||
129 | 1 | static int get_id3_tag(AVFormatContext *s, int len) | |
130 | { | ||
131 | ID3v2ExtraMeta *id3v2_extra_meta; | ||
132 | |||
133 | 1 | ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len); | |
134 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (id3v2_extra_meta) { |
135 | 1 | ff_id3v2_parse_apic(s, id3v2_extra_meta); | |
136 | 1 | ff_id3v2_parse_chapters(s, id3v2_extra_meta); | |
137 | 1 | ff_id3v2_free_extra_meta(&id3v2_extra_meta); | |
138 | } | ||
139 | 1 | return 0; | |
140 | } | ||
141 | |||
142 | 16 | int ff_asf_handle_byte_array(AVFormatContext *s, const char *name, | |
143 | int val_len) | ||
144 | { | ||
145 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 13 times.
|
16 | if (!strcmp(name, "WM/Picture")) // handle cover art |
146 | 3 | return asf_read_picture(s, val_len); | |
147 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
|
13 | else if (!strcmp(name, "ID3")) // handle ID3 tag |
148 | 1 | return get_id3_tag(s, val_len); | |
149 | |||
150 | 12 | return 1; | |
151 | } | ||
152 |