mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
id3v2: read attached pictures and export them in ID3v2ExtraMeta.
This commit is contained in:
parent
b73ad74660
commit
a93b09cb45
@ -25,6 +25,7 @@
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "avio_internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
|
||||
{ "TALB", "album"},
|
||||
@ -86,6 +87,38 @@ const char ff_id3v2_3_tags[][4] = {
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
const char *ff_id3v2_picture_types[21] = {
|
||||
"Other",
|
||||
"32x32 pixels 'file icon'",
|
||||
"Other file icon",
|
||||
"Cover (front)",
|
||||
"Cover (back)",
|
||||
"Leaflet page",
|
||||
"Media (e.g. label side of CD)",
|
||||
"Lead artist/lead performer/soloist",
|
||||
"Artist/performer",
|
||||
"Conductor",
|
||||
"Band/Orchestra",
|
||||
"Composer",
|
||||
"Lyricist/text writer",
|
||||
"Recording Location",
|
||||
"During recording",
|
||||
"During performance",
|
||||
"Movie/video screen capture",
|
||||
"A bright coloured fish",
|
||||
"Illustration",
|
||||
"Band/artist logotype",
|
||||
"Publisher/Studio logotype",
|
||||
};
|
||||
|
||||
const CodecMime ff_id3v2_mime_tags[] = {
|
||||
{"image/gif" , CODEC_ID_GIF},
|
||||
{"image/jpeg", CODEC_ID_MJPEG},
|
||||
{"image/png" , CODEC_ID_PNG},
|
||||
{"image/tiff", CODEC_ID_TIFF},
|
||||
{"", CODEC_ID_NONE},
|
||||
};
|
||||
|
||||
int ff_id3v2_match(const uint8_t *buf, const char * magic)
|
||||
{
|
||||
return buf[0] == magic[0] &&
|
||||
@ -381,6 +414,84 @@ finish:
|
||||
av_dict_set(m, "date", date, 0);
|
||||
}
|
||||
|
||||
static void free_apic(void *obj)
|
||||
{
|
||||
ID3v2ExtraMetaAPIC *apic = obj;
|
||||
av_freep(&apic->data);
|
||||
av_freep(&apic->description);
|
||||
av_freep(&apic);
|
||||
}
|
||||
|
||||
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
|
||||
{
|
||||
int enc, pic_type;
|
||||
char mimetype[64];
|
||||
const CodecMime *mime = ff_id3v2_mime_tags;
|
||||
enum CodecID id = CODEC_ID_NONE;
|
||||
ID3v2ExtraMetaAPIC *apic = NULL;
|
||||
ID3v2ExtraMeta *new_extra = NULL;
|
||||
int64_t end = avio_tell(pb) + taglen;
|
||||
|
||||
if (taglen <= 4)
|
||||
goto fail;
|
||||
|
||||
new_extra = av_mallocz(sizeof(*new_extra));
|
||||
apic = av_mallocz(sizeof(*apic));
|
||||
if (!new_extra || !apic)
|
||||
goto fail;
|
||||
|
||||
enc = avio_r8(pb);
|
||||
taglen--;
|
||||
|
||||
/* mimetype */
|
||||
taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype));
|
||||
while (mime->id != CODEC_ID_NONE) {
|
||||
if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
|
||||
id = mime->id;
|
||||
break;
|
||||
}
|
||||
mime++;
|
||||
}
|
||||
if (id == CODEC_ID_NONE) {
|
||||
av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
|
||||
goto fail;
|
||||
}
|
||||
apic->id = id;
|
||||
|
||||
/* picture type */
|
||||
pic_type = avio_r8(pb);
|
||||
taglen--;
|
||||
if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
|
||||
av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type);
|
||||
pic_type = 0;
|
||||
}
|
||||
apic->type = ff_id3v2_picture_types[pic_type];
|
||||
|
||||
/* description and picture data */
|
||||
if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
apic->len = taglen;
|
||||
apic->data = av_malloc(taglen);
|
||||
if (!apic->data || avio_read(pb, apic->data, taglen) != taglen)
|
||||
goto fail;
|
||||
|
||||
new_extra->tag = "APIC";
|
||||
new_extra->data = apic;
|
||||
new_extra->next = *extra_meta;
|
||||
*extra_meta = new_extra;
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
if (apic)
|
||||
free_apic(apic);
|
||||
av_freep(&new_extra);
|
||||
avio_seek(pb, end, SEEK_SET);
|
||||
}
|
||||
|
||||
typedef struct ID3v2EMFunc {
|
||||
const char *tag3;
|
||||
const char *tag4;
|
||||
@ -390,6 +501,7 @@ typedef struct ID3v2EMFunc {
|
||||
|
||||
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
|
||||
{ "GEO", "GEOB", read_geobtag, free_geobtag },
|
||||
{ "PIC", "APIC", read_apic, free_apic },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
#include "metadata.h"
|
||||
|
||||
#define ID3v2_HEADER_SIZE 10
|
||||
@ -59,6 +60,14 @@ typedef struct ID3v2ExtraMetaGEOB {
|
||||
uint8_t *data;
|
||||
} ID3v2ExtraMetaGEOB;
|
||||
|
||||
typedef struct ID3v2ExtraMetaAPIC {
|
||||
uint8_t *data;
|
||||
int len;
|
||||
const char *type;
|
||||
uint8_t *description;
|
||||
enum CodecID id;
|
||||
} ID3v2ExtraMetaAPIC;
|
||||
|
||||
/**
|
||||
* Detect ID3v2 Header.
|
||||
* @param buf must be ID3v2_HEADER_SIZE byte long
|
||||
@ -120,4 +129,8 @@ extern const char ff_id3v2_4_tags[][4];
|
||||
*/
|
||||
extern const char ff_id3v2_3_tags[][4];
|
||||
|
||||
extern const CodecMime ff_id3v2_mime_tags[];
|
||||
|
||||
extern const char *ff_id3v2_picture_types[21];
|
||||
|
||||
#endif /* AVFORMAT_ID3V2_H */
|
||||
|
Loading…
Reference in New Issue
Block a user