lavf: export id3v2 attached pictures as streams.
This commit is contained in:
parent
dd2a4bcfd7
commit
079ea6ca5f
@ -702,3 +702,37 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
|
|||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
|
||||||
|
{
|
||||||
|
ID3v2ExtraMeta *cur;
|
||||||
|
|
||||||
|
for (cur = *extra_meta; cur; cur = cur->next) {
|
||||||
|
ID3v2ExtraMetaAPIC *apic;
|
||||||
|
AVStream *st;
|
||||||
|
|
||||||
|
if (strcmp(cur->tag, "APIC"))
|
||||||
|
continue;
|
||||||
|
apic = cur->data;
|
||||||
|
|
||||||
|
if (!(st = avformat_new_stream(s, NULL)))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
||||||
|
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
st->codec->codec_id = apic->id;
|
||||||
|
av_dict_set(&st->metadata, "title", apic->description, 0);
|
||||||
|
av_dict_set(&st->metadata, "comment", apic->type, 0);
|
||||||
|
|
||||||
|
av_init_packet(&st->attached_pic);
|
||||||
|
st->attached_pic.data = apic->data;
|
||||||
|
st->attached_pic.size = apic->len;
|
||||||
|
st->attached_pic.destruct = av_destruct_packet;
|
||||||
|
st->attached_pic.stream_index = st->index;
|
||||||
|
|
||||||
|
apic->data = NULL;
|
||||||
|
apic->len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -109,6 +109,12 @@ int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version, const char *mag
|
|||||||
*/
|
*/
|
||||||
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
|
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a stream for each APIC (attached picture) extracted from the
|
||||||
|
* ID3v2 header.
|
||||||
|
*/
|
||||||
|
int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta);
|
||||||
|
|
||||||
extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
|
extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
|
||||||
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
|
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
|
||||||
|
|
||||||
|
@ -520,6 +520,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
|
|||||||
AVFormatContext *s = *ps;
|
AVFormatContext *s = *ps;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
AVDictionary *tmp = NULL;
|
AVDictionary *tmp = NULL;
|
||||||
|
ID3v2ExtraMeta *id3v2_extra_meta = NULL;
|
||||||
|
|
||||||
if (!s && !(s = avformat_alloc_context()))
|
if (!s && !(s = avformat_alloc_context()))
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
@ -562,12 +563,17 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
|
|||||||
|
|
||||||
/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
|
/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
|
||||||
if (s->pb)
|
if (s->pb)
|
||||||
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
|
ff_id3v2_read_all(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
|
||||||
|
|
||||||
if (s->iformat->read_header)
|
if (s->iformat->read_header)
|
||||||
if ((ret = s->iformat->read_header(s)) < 0)
|
if ((ret = s->iformat->read_header(s)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (id3v2_extra_meta &&
|
||||||
|
(ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
|
||||||
|
goto fail;
|
||||||
|
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
|
||||||
|
|
||||||
/* queue attached pictures */
|
/* queue attached pictures */
|
||||||
for (i = 0; i < s->nb_streams; i++)
|
for (i = 0; i < s->nb_streams; i++)
|
||||||
if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
|
if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
|
||||||
@ -589,6 +595,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
|
||||||
av_dict_free(&tmp);
|
av_dict_free(&tmp);
|
||||||
if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
|
if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
|
||||||
avio_close(s->pb);
|
avio_close(s->pb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user