matroskadec: export cover art correctly
Generally, libavformat exports cover art pictures as video streams with 1 packet and AV_DISPOSITION_ATTACHED_PIC set. Only matroskadec exported it as attachment with codec_id set to AV_CODEC_ID_MJPEG. Obviously, this should be consistent, so change the Matroska demuxer to export a AV_DISPOSITION_ATTACHED_PIC pseudo video stream. Matroska muxing is probably incorrect too. I know that it can create broken files with an audio track and just 1 video frame when e.g. remuxing mp3 with APIC to mkv. But for now this commit does not change anything about muxing, and also continues to write attachments with AV_CODEC_ID_MJPEG should the muxer application have special knowledge that the Matroska is broken in this way. Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
parent
27f2746282
commit
c4d37cd9ef
@ -89,12 +89,17 @@ const CodecTags ff_mkv_codec_tags[]={
|
|||||||
{"" , AV_CODEC_ID_NONE}
|
{"" , AV_CODEC_ID_NONE}
|
||||||
};
|
};
|
||||||
|
|
||||||
const CodecMime ff_mkv_mime_tags[] = {
|
const CodecMime ff_mkv_image_mime_tags[] = {
|
||||||
{"text/plain" , AV_CODEC_ID_TEXT},
|
|
||||||
{"image/gif" , AV_CODEC_ID_GIF},
|
{"image/gif" , AV_CODEC_ID_GIF},
|
||||||
{"image/jpeg" , AV_CODEC_ID_MJPEG},
|
{"image/jpeg" , AV_CODEC_ID_MJPEG},
|
||||||
{"image/png" , AV_CODEC_ID_PNG},
|
{"image/png" , AV_CODEC_ID_PNG},
|
||||||
{"image/tiff" , AV_CODEC_ID_TIFF},
|
{"image/tiff" , AV_CODEC_ID_TIFF},
|
||||||
|
|
||||||
|
{"" , AV_CODEC_ID_NONE}
|
||||||
|
};
|
||||||
|
|
||||||
|
const CodecMime ff_mkv_mime_tags[] = {
|
||||||
|
{"text/plain" , AV_CODEC_ID_TEXT},
|
||||||
{"application/x-truetype-font", AV_CODEC_ID_TTF},
|
{"application/x-truetype-font", AV_CODEC_ID_TTF},
|
||||||
{"application/x-font" , AV_CODEC_ID_TTF},
|
{"application/x-font" , AV_CODEC_ID_TTF},
|
||||||
|
|
||||||
|
@ -254,6 +254,7 @@ typedef struct CodecTags{
|
|||||||
|
|
||||||
extern const CodecTags ff_mkv_codec_tags[];
|
extern const CodecTags ff_mkv_codec_tags[];
|
||||||
extern const CodecMime ff_mkv_mime_tags[];
|
extern const CodecMime ff_mkv_mime_tags[];
|
||||||
|
extern const CodecMime ff_mkv_image_mime_tags[];
|
||||||
extern const AVMetadataConv ff_mkv_metadata_conv[];
|
extern const AVMetadataConv ff_mkv_metadata_conv[];
|
||||||
|
|
||||||
int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode);
|
int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode);
|
||||||
|
@ -1887,22 +1887,45 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
av_dict_set(&st->metadata, "filename", attachments[j].filename, 0);
|
av_dict_set(&st->metadata, "filename", attachments[j].filename, 0);
|
||||||
av_dict_set(&st->metadata, "mimetype", attachments[j].mime, 0);
|
av_dict_set(&st->metadata, "mimetype", attachments[j].mime, 0);
|
||||||
st->codec->codec_id = AV_CODEC_ID_NONE;
|
st->codec->codec_id = AV_CODEC_ID_NONE;
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
|
||||||
st->codec->extradata = av_malloc(attachments[j].bin.size);
|
|
||||||
if (!st->codec->extradata)
|
|
||||||
break;
|
|
||||||
st->codec->extradata_size = attachments[j].bin.size;
|
|
||||||
memcpy(st->codec->extradata, attachments[j].bin.data,
|
|
||||||
attachments[j].bin.size);
|
|
||||||
|
|
||||||
for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
|
for (i = 0; ff_mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
|
||||||
if (!strncmp(ff_mkv_mime_tags[i].str, attachments[j].mime,
|
if (!strncmp(ff_mkv_image_mime_tags[i].str, attachments[j].mime,
|
||||||
strlen(ff_mkv_mime_tags[i].str))) {
|
strlen(ff_mkv_image_mime_tags[i].str))) {
|
||||||
st->codec->codec_id = ff_mkv_mime_tags[i].id;
|
st->codec->codec_id = ff_mkv_image_mime_tags[i].id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attachments[j].stream = st;
|
attachments[j].stream = st;
|
||||||
|
|
||||||
|
if (st->codec->codec_id != AV_CODEC_ID_NONE) {
|
||||||
|
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
||||||
|
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
|
||||||
|
av_init_packet(&st->attached_pic);
|
||||||
|
if ((res = av_new_packet(&st->attached_pic, attachments[j].bin.size)) < 0)
|
||||||
|
return res;
|
||||||
|
memcpy(st->attached_pic.data, attachments[j].bin.data, attachments[j].bin.size);
|
||||||
|
st->attached_pic.stream_index = st->index;
|
||||||
|
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
||||||
|
} else {
|
||||||
|
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
||||||
|
st->codec->extradata = av_malloc(attachments[j].bin.size);
|
||||||
|
if (!st->codec->extradata)
|
||||||
|
break;
|
||||||
|
|
||||||
|
st->codec->extradata_size = attachments[j].bin.size;
|
||||||
|
memcpy(st->codec->extradata, attachments[j].bin.data,
|
||||||
|
attachments[j].bin.size);
|
||||||
|
|
||||||
|
for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
|
||||||
|
if (!strncmp(ff_mkv_mime_tags[i].str, attachments[j].mime,
|
||||||
|
strlen(ff_mkv_mime_tags[i].str))) {
|
||||||
|
st->codec->codec_id = ff_mkv_mime_tags[i].id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,6 +1098,11 @@ static int mkv_write_attachments(AVFormatContext *s)
|
|||||||
mimetype = ff_mkv_mime_tags[i].str;
|
mimetype = ff_mkv_mime_tags[i].str;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
for (i = 0; ff_mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++)
|
||||||
|
if (ff_mkv_image_mime_tags[i].id == st->codec->codec_id) {
|
||||||
|
mimetype = ff_mkv_image_mime_tags[i].str;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!mimetype) {
|
if (!mimetype) {
|
||||||
av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and "
|
av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and "
|
||||||
|
Loading…
x
Reference in New Issue
Block a user