mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-27 01:42:20 +00:00
avformat: Add and use helper function to add attachment streams
All instances of adding attached pictures to a stream or adding a stream and an attached packet to said stream have several things in common like setting the index and flags of the packet, setting the stream disposition etc. This commit therefore factors this out. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
b7b73e83e3
commit
39ecb63d0f
@ -79,20 +79,12 @@ static int ape_tag_read_field(AVFormatContext *s)
|
|||||||
av_dict_set(&st->metadata, key, filename, 0);
|
av_dict_set(&st->metadata, key, filename, 0);
|
||||||
|
|
||||||
if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) {
|
if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) {
|
||||||
int ret;
|
int ret = ff_add_attached_pic(s, st, s->pb, NULL, size);
|
||||||
|
|
||||||
ret = av_get_packet(s->pb, &st->attached_pic, size);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(s, AV_LOG_ERROR, "Error reading cover art.\n");
|
av_log(s, AV_LOG_ERROR, "Error reading cover art.\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codecpar->codec_id = id;
|
st->codecpar->codec_id = id;
|
||||||
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
} else {
|
} else {
|
||||||
if ((ret = ff_get_extradata(s, st->codecpar, s->pb, size)) < 0)
|
if ((ret = ff_get_extradata(s, st->codecpar, s->pb, size)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -160,20 +160,11 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int tr
|
|||||||
if (AV_RB64(data->data) == PNGSIG)
|
if (AV_RB64(data->data) == PNGSIG)
|
||||||
id = AV_CODEC_ID_PNG;
|
id = AV_CODEC_ID_PNG;
|
||||||
|
|
||||||
st = avformat_new_stream(s, NULL);
|
ret = ff_add_attached_pic(s, NULL, NULL, &data, 0);
|
||||||
if (!st) {
|
if (ret < 0)
|
||||||
RETURN_ERROR(AVERROR(ENOMEM));
|
RETURN_ERROR(ret);
|
||||||
}
|
|
||||||
|
|
||||||
av_packet_unref(&st->attached_pic);
|
st = s->streams[s->nb_streams - 1];
|
||||||
st->attached_pic.buf = data;
|
|
||||||
st->attached_pic.data = data->data;
|
|
||||||
st->attached_pic.size = len;
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
|
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codecpar->codec_id = id;
|
st->codecpar->codec_id = id;
|
||||||
st->codecpar->width = width;
|
st->codecpar->width = width;
|
||||||
st->codecpar->height = height;
|
st->codecpar->height = height;
|
||||||
|
@ -1142,34 +1142,25 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
|
|||||||
for (cur = extra_meta; cur; cur = cur->next) {
|
for (cur = extra_meta; cur; cur = cur->next) {
|
||||||
ID3v2ExtraMetaAPIC *apic;
|
ID3v2ExtraMetaAPIC *apic;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (strcmp(cur->tag, "APIC"))
|
if (strcmp(cur->tag, "APIC"))
|
||||||
continue;
|
continue;
|
||||||
apic = &cur->data.apic;
|
apic = &cur->data.apic;
|
||||||
|
|
||||||
if (!(st = avformat_new_stream(s, NULL)))
|
ret = ff_add_attached_pic(s, NULL, NULL, &apic->buf, 0);
|
||||||
return AVERROR(ENOMEM);
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
st = s->streams[s->nb_streams - 1];
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codecpar->codec_id = apic->id;
|
st->codecpar->codec_id = apic->id;
|
||||||
|
|
||||||
if (AV_RB64(apic->buf->data) == PNGSIG)
|
if (AV_RB64(st->attached_pic.data) == PNGSIG)
|
||||||
st->codecpar->codec_id = AV_CODEC_ID_PNG;
|
st->codecpar->codec_id = AV_CODEC_ID_PNG;
|
||||||
|
|
||||||
if (apic->description[0])
|
if (apic->description[0])
|
||||||
av_dict_set(&st->metadata, "title", apic->description, 0);
|
av_dict_set(&st->metadata, "title", apic->description, 0);
|
||||||
|
|
||||||
av_dict_set(&st->metadata, "comment", apic->type, 0);
|
av_dict_set(&st->metadata, "comment", apic->type, 0);
|
||||||
|
|
||||||
av_packet_unref(&st->attached_pic);
|
|
||||||
st->attached_pic.buf = apic->buf;
|
|
||||||
st->attached_pic.data = apic->buf->data;
|
|
||||||
st->attached_pic.size = apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE;
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
|
|
||||||
apic->buf = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -669,6 +669,19 @@ int ff_framehash_write_header(AVFormatContext *s);
|
|||||||
*/
|
*/
|
||||||
int ff_read_packet(AVFormatContext *s, AVPacket *pkt);
|
int ff_read_packet(AVFormatContext *s, AVPacket *pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attached pic to an AVStream.
|
||||||
|
*
|
||||||
|
* @param st if set, the stream to add the attached pic to;
|
||||||
|
* if unset, a new stream will be added to s.
|
||||||
|
* @param pb AVIOContext to read data from if buf is unset.
|
||||||
|
* @param buf if set, it contains the data and size information to be used
|
||||||
|
* for the attached pic; if unset, data is read from pb.
|
||||||
|
* @param size the size of the data to read if buf is unset.
|
||||||
|
*/
|
||||||
|
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb,
|
||||||
|
AVBufferRef **buf, int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interleave an AVPacket per dts so it can be muxed.
|
* Interleave an AVPacket per dts so it can be muxed.
|
||||||
*
|
*
|
||||||
|
@ -3007,18 +3007,9 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
attachments[j].stream = st;
|
attachments[j].stream = st;
|
||||||
|
|
||||||
if (st->codecpar->codec_id != AV_CODEC_ID_NONE) {
|
if (st->codecpar->codec_id != AV_CODEC_ID_NONE) {
|
||||||
AVPacket *pkt = &st->attached_pic;
|
res = ff_add_attached_pic(s, st, NULL, &attachments[j].bin.buf, 0);
|
||||||
|
if (res < 0)
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
goto fail;
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
|
|
||||||
av_packet_unref(pkt);
|
|
||||||
pkt->buf = attachments[j].bin.buf;
|
|
||||||
attachments[j].bin.buf = NULL;
|
|
||||||
pkt->data = attachments[j].bin.data;
|
|
||||||
pkt->size = attachments[j].bin.size;
|
|
||||||
pkt->stream_index = st->index;
|
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
|
||||||
} else {
|
} else {
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
st->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
||||||
if (ff_alloc_extradata(st->codecpar, attachments[j].bin.size))
|
if (ff_alloc_extradata(st->codecpar, attachments[j].bin.size))
|
||||||
|
@ -196,17 +196,16 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
st = avformat_new_stream(c->fc, NULL);
|
|
||||||
if (!st)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
sc = av_mallocz(sizeof(*sc));
|
sc = av_mallocz(sizeof(*sc));
|
||||||
if (!sc)
|
if (!sc)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
st->priv_data = sc;
|
ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
|
||||||
|
if (ret < 0) {
|
||||||
ret = av_get_packet(pb, &st->attached_pic, len);
|
av_free(sc);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
st = c->fc->streams[c->fc->nb_streams - 1];
|
||||||
|
st->priv_data = sc;
|
||||||
|
|
||||||
if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
|
if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
|
||||||
if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
|
if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
|
||||||
@ -215,13 +214,6 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
|
|||||||
id = AV_CODEC_ID_MJPEG;
|
id = AV_CODEC_ID_MJPEG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
|
||||||
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
|
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codecpar->codec_id = id;
|
st->codecpar->codec_id = id;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -7233,11 +7225,8 @@ static void mov_read_chapters(AVFormatContext *s)
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
|
if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
|
st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
|
||||||
|
@ -474,6 +474,36 @@ int avformat_queue_attached_pictures(AVFormatContext *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb,
|
||||||
|
AVBufferRef **buf, int size)
|
||||||
|
{
|
||||||
|
AVPacket *pkt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!st && !(st = avformat_new_stream(s, NULL)))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
pkt = &st->attached_pic;
|
||||||
|
if (buf) {
|
||||||
|
av_assert1(*buf);
|
||||||
|
av_packet_unref(pkt);
|
||||||
|
pkt->buf = *buf;
|
||||||
|
pkt->data = (*buf)->data;
|
||||||
|
pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
|
||||||
|
*buf = NULL;
|
||||||
|
} else {
|
||||||
|
ret = av_get_packet(pb, pkt, size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
||||||
|
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
|
||||||
|
pkt->stream_index = st->index;
|
||||||
|
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int update_stream_avctx(AVFormatContext *s)
|
static int update_stream_avctx(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
@ -434,7 +434,6 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
|
|||||||
char description[1024];
|
char description[1024];
|
||||||
unsigned int filesize;
|
unsigned int filesize;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
int ret;
|
|
||||||
int64_t pos = avio_tell(pb);
|
int64_t pos = avio_tell(pb);
|
||||||
|
|
||||||
avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
|
avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
|
||||||
@ -447,19 +446,12 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
|
|||||||
if (!filesize)
|
if (!filesize)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
st = avformat_new_stream(s, NULL);
|
if (ff_add_attached_pic(s, NULL, pb, NULL, filesize) < 0)
|
||||||
if (!st)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
st = s->streams[s->nb_streams - 1];
|
||||||
av_dict_set(&st->metadata, "title", description, 0);
|
av_dict_set(&st->metadata, "title", description, 0);
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codecpar->codec_id = AV_CODEC_ID_MJPEG;
|
st->codecpar->codec_id = AV_CODEC_ID_MJPEG;
|
||||||
st->id = -1;
|
st->id = -1;
|
||||||
ret = av_get_packet(pb, &st->attached_pic, filesize);
|
|
||||||
if (ret < 0)
|
|
||||||
goto done;
|
|
||||||
st->attached_pic.stream_index = st->index;
|
|
||||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
|
||||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
|
||||||
done:
|
done:
|
||||||
avio_seek(pb, pos + length, SEEK_SET);
|
avio_seek(pb, pos + length, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user