mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-21 14:53:10 +00:00
avformat/matroskadec: Factor parsing content encodings out
Namely, out of matroska_parse_tracks(). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
b105ad50c5
commit
4e633e51da
@ -2029,6 +2029,80 @@ static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
|
|||||||
matroska_add_index_entries(matroska);
|
matroska_add_index_entries(matroska);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int matroska_parse_content_encodings(MatroskaTrackEncoding *encodings,
|
||||||
|
unsigned nb_encodings,
|
||||||
|
MatroskaTrack *track,
|
||||||
|
char **key_id_base64, void *logctx)
|
||||||
|
{
|
||||||
|
if (nb_encodings > 1) {
|
||||||
|
av_log(logctx, AV_LOG_ERROR,
|
||||||
|
"Multiple combined encodings not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!nb_encodings)
|
||||||
|
return 0;
|
||||||
|
if (encodings->type) {
|
||||||
|
if (encodings->encryption.key_id.size > 0) {
|
||||||
|
/* Save the encryption key id to be stored later
|
||||||
|
* as a metadata tag. */
|
||||||
|
const int b64_size = AV_BASE64_SIZE(encodings->encryption.key_id.size);
|
||||||
|
*key_id_base64 = av_malloc(b64_size);
|
||||||
|
if (!*key_id_base64)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
av_base64_encode(*key_id_base64, b64_size,
|
||||||
|
encodings->encryption.key_id.data,
|
||||||
|
encodings->encryption.key_id.size);
|
||||||
|
} else {
|
||||||
|
encodings->scope = 0;
|
||||||
|
av_log(logctx, AV_LOG_ERROR, "Unsupported encoding type");
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
#if CONFIG_ZLIB
|
||||||
|
encodings->compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB &&
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BZLIB
|
||||||
|
encodings->compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB &&
|
||||||
|
#endif
|
||||||
|
encodings->compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO &&
|
||||||
|
encodings->compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
|
||||||
|
encodings->scope = 0;
|
||||||
|
av_log(logctx, AV_LOG_ERROR, "Unsupported encoding type");
|
||||||
|
} else if (track->codec_priv.size && encodings[0].scope & 2) {
|
||||||
|
uint8_t *codec_priv = track->codec_priv.data;
|
||||||
|
int ret = matroska_decode_buffer(&track->codec_priv.data,
|
||||||
|
&track->codec_priv.size,
|
||||||
|
track);
|
||||||
|
if (ret < 0) {
|
||||||
|
track->codec_priv.data = NULL;
|
||||||
|
track->codec_priv.size = 0;
|
||||||
|
av_log(logctx, AV_LOG_ERROR,
|
||||||
|
"Failed to decode codec private data\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec_priv != track->codec_priv.data) {
|
||||||
|
av_buffer_unref(&track->codec_priv.buf);
|
||||||
|
if (track->codec_priv.data) {
|
||||||
|
track->codec_priv.buf = av_buffer_create(track->codec_priv.data,
|
||||||
|
track->codec_priv.size + AV_INPUT_BUFFER_PADDING_SIZE,
|
||||||
|
NULL, NULL, 0);
|
||||||
|
if (!track->codec_priv.buf) {
|
||||||
|
av_freep(&track->codec_priv.data);
|
||||||
|
track->codec_priv.size = 0;
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
track->needs_decoding = !encodings->type &&
|
||||||
|
encodings->scope & 1 &&
|
||||||
|
(encodings->compression.algo !=
|
||||||
|
MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP ||
|
||||||
|
encodings->compression.settings.size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int matroska_aac_profile(char *codec_id)
|
static int matroska_aac_profile(char *codec_id)
|
||||||
{
|
{
|
||||||
static const char *const aac_profiles[] = { "MAIN", "LC", "SSR" };
|
static const char *const aac_profiles[] = { "MAIN", "LC", "SSR" };
|
||||||
@ -3008,8 +3082,6 @@ static int matroska_parse_tracks(AVFormatContext *s)
|
|||||||
for (i = 0; i < matroska->tracks.nb_elem; i++) {
|
for (i = 0; i < matroska->tracks.nb_elem; i++) {
|
||||||
MatroskaTrack *track = &tracks[i];
|
MatroskaTrack *track = &tracks[i];
|
||||||
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
||||||
EbmlList *encodings_list = &track->encodings;
|
|
||||||
MatroskaTrackEncoding *encodings = encodings_list->elem;
|
|
||||||
AVCodecParameters *par;
|
AVCodecParameters *par;
|
||||||
MatroskaTrackType type;
|
MatroskaTrackType type;
|
||||||
int extradata_offset = 0;
|
int extradata_offset = 0;
|
||||||
@ -3065,71 +3137,11 @@ static int matroska_parse_tracks(AVFormatContext *s)
|
|||||||
if (!track->audio.out_samplerate)
|
if (!track->audio.out_samplerate)
|
||||||
track->audio.out_samplerate = track->audio.samplerate;
|
track->audio.out_samplerate = track->audio.samplerate;
|
||||||
}
|
}
|
||||||
if (encodings_list->nb_elem > 1) {
|
ret = matroska_parse_content_encodings(track->encodings.elem,
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
track->encodings.nb_elem,
|
||||||
"Multiple combined encodings not supported");
|
track, &key_id_base64, matroska->ctx);
|
||||||
} else if (encodings_list->nb_elem == 1) {
|
if (ret < 0)
|
||||||
if (encodings[0].type) {
|
return ret;
|
||||||
if (encodings[0].encryption.key_id.size > 0) {
|
|
||||||
/* Save the encryption key id to be stored later as a
|
|
||||||
metadata tag. */
|
|
||||||
const int b64_size = AV_BASE64_SIZE(encodings[0].encryption.key_id.size);
|
|
||||||
key_id_base64 = av_malloc(b64_size);
|
|
||||||
if (key_id_base64 == NULL)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
av_base64_encode(key_id_base64, b64_size,
|
|
||||||
encodings[0].encryption.key_id.data,
|
|
||||||
encodings[0].encryption.key_id.size);
|
|
||||||
} else {
|
|
||||||
encodings[0].scope = 0;
|
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
|
||||||
"Unsupported encoding type");
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
#if CONFIG_ZLIB
|
|
||||||
encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB &&
|
|
||||||
#endif
|
|
||||||
#if CONFIG_BZLIB
|
|
||||||
encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB &&
|
|
||||||
#endif
|
|
||||||
encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO &&
|
|
||||||
encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
|
|
||||||
encodings[0].scope = 0;
|
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
|
||||||
"Unsupported encoding type");
|
|
||||||
} else if (track->codec_priv.size && encodings[0].scope & 2) {
|
|
||||||
uint8_t *codec_priv = track->codec_priv.data;
|
|
||||||
int ret = matroska_decode_buffer(&track->codec_priv.data,
|
|
||||||
&track->codec_priv.size,
|
|
||||||
track);
|
|
||||||
if (ret < 0) {
|
|
||||||
track->codec_priv.data = NULL;
|
|
||||||
track->codec_priv.size = 0;
|
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
|
||||||
"Failed to decode codec private data\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codec_priv != track->codec_priv.data) {
|
|
||||||
av_buffer_unref(&track->codec_priv.buf);
|
|
||||||
if (track->codec_priv.data) {
|
|
||||||
track->codec_priv.buf = av_buffer_create(track->codec_priv.data,
|
|
||||||
track->codec_priv.size + AV_INPUT_BUFFER_PADDING_SIZE,
|
|
||||||
NULL, NULL, 0);
|
|
||||||
if (!track->codec_priv.buf) {
|
|
||||||
av_freep(&track->codec_priv.data);
|
|
||||||
track->codec_priv.size = 0;
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
track->needs_decoding = encodings && !encodings[0].type &&
|
|
||||||
encodings[0].scope & 1 &&
|
|
||||||
(encodings[0].compression.algo !=
|
|
||||||
MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP ||
|
|
||||||
encodings[0].compression.settings.size);
|
|
||||||
|
|
||||||
for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
|
for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) {
|
||||||
if (av_strstart(track->codec_id, ff_mkv_codec_tags[j].str, NULL)) {
|
if (av_strstart(track->codec_id, ff_mkv_codec_tags[j].str, NULL)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user