diff --git a/libavformat/mov.c b/libavformat/mov.c index 63254012fc..6ddecd182d 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -166,6 +166,48 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, return p - dst; } +static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) +{ + AVPacket pkt; + AVStream *st; + MOVStreamContext *sc; + enum CodecID id; + int ret; + + switch (type) { + case 0xd: id = CODEC_ID_MJPEG; break; + case 0xe: id = CODEC_ID_PNG; break; + case 0x1b: id = CODEC_ID_BMP; break; + default: + av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type); + avio_skip(pb, len); + return 0; + } + + st = avformat_new_stream(c->fc, NULL); + if (!st) + return AVERROR(ENOMEM); + sc = av_mallocz(sizeof(*sc)); + if (!sc) + return AVERROR(ENOMEM); + st->priv_data = sc; + + ret = av_get_packet(pb, &pkt, len); + if (ret < 0) + return ret; + + st->disposition |= AV_DISPOSITION_ATTACHED_PIC; + + st->attached_pic = pkt; + st->attached_pic.stream_index = st->index; + st->attached_pic.flags |= AV_PKT_FLAG_KEY; + + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->codec_id = id; + + return 0; +} + static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) { #ifdef MOV_EXPORT_ALL_METADATA @@ -224,6 +266,14 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb32(pb); // unknown str_size = data_size - 16; atom.size -= 16; + + if (atom.type == MKTAG('c', 'o', 'v', 'r')) { + int ret = mov_read_covr(c, pb, data_type, str_size); + if (ret < 0) { + av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n"); + return ret; + } + } } else return 0; } else if (atom.size > 4 && key && !c->itunes_metadata) { str_size = avio_rb16(pb); // string length