[FFmpeg-devel] [PATCH] lavf/matroska: expose stream encoding as global side-data
James Almer
jamrial at gmail.com
Sat Sep 10 07:19:20 EEST 2016
On 9/10/2016 12:39 AM, Rodger Combs wrote:
> Some demuxers can't handle Matroska compression, so this lets API users
> check if a file uses it and determine whether those players will fail.
> ---
> libavcodec/avcodec.h | 35 ++++++++++++++++++++++++++++++++++-
> libavcodec/avpacket.c | 1 +
> libavcodec/version.h | 4 ++--
> libavformat/matroskadec.c | 23 +++++++++++++++++------
> 4 files changed, 54 insertions(+), 9 deletions(-)
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 01f9b29..0ecc6b4 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -1330,6 +1330,34 @@ typedef struct AVCPBProperties {
> uint64_t vbv_delay;
> } AVCPBProperties;
>
> +/**
> + * This structure describes the Matroska encoding (compression or encryption) applied to
> + * a stream. It can be useful when determining whether or not other demuxers can handle
> + * a file, since some players don't support header compression.
> + */
> +typedef struct AVMatroskaEncoding {
> + /**
> + * Type of content encoding. 0 for compression; 1 for encryption.
> + */
> + uint64_t type;
If it's a boolean value then just use int/unsigned.
> + /**
> + * Algorithm used for the compression or encryption.
> + * For compression:
> + * 0 - zlib,
> + * 1 - bzlib,
> + * 2 - lzo1x
> + * 3 - Header Stripping
> + * For encryption:
> + * 0 - Signing only
> + * 1 - DES
> + * 2 - 3DES
> + * 3 - Twofish
> + * 4 - Blowfish
> + * 5 - AES
> + */
> + uint64_t algorithm;
Enum? Otherwise int/unsigned and ideally #defines.
> +} AVMatroskaEncoding;
> +
> #if FF_API_QSCALE_TYPE
> #define FF_QSCALE_TYPE_MPEG1 0
> #define FF_QSCALE_TYPE_MPEG2 1
> @@ -1525,7 +1553,12 @@ enum AVPacketSideDataType {
> * should be associated with a video stream and containts data in the form
> * of the AVMasteringDisplayMetadata struct.
> */
> - AV_PKT_DATA_MASTERING_DISPLAY_METADATA
> + AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
> +
> + /**
> + * Corresponds to the AVMatroskaEncoding struct.
> + */
> + AV_PKT_DATA_MATROSKA_ENCODING,
> };
>
> #define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
> index fa2844d..220e305 100644
> --- a/libavcodec/avpacket.c
> +++ b/libavcodec/avpacket.c
> @@ -367,6 +367,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type)
> case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update";
> case AV_PKT_DATA_MPEGTS_STREAM_ID: return "MPEGTS Stream ID";
> case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata";
> + case AV_PKT_DATA_MATROSKA_ENCODING: return "Matroska Encoding";
> }
> return NULL;
> }
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index f5dd118..ecd48c5 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -28,8 +28,8 @@
> #include "libavutil/version.h"
>
> #define LIBAVCODEC_VERSION_MAJOR 57
> -#define LIBAVCODEC_VERSION_MINOR 55
> -#define LIBAVCODEC_VERSION_MICRO 101
> +#define LIBAVCODEC_VERSION_MINOR 56
> +#define LIBAVCODEC_VERSION_MICRO 100
>
> #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> LIBAVCODEC_VERSION_MINOR, \
> diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
> index 77b8a5d..9bae9c8 100644
> --- a/libavformat/matroskadec.c
> +++ b/libavformat/matroskadec.c
> @@ -1919,6 +1919,10 @@ static int matroska_parse_tracks(AVFormatContext *s)
> if (!track->codec_id)
> continue;
>
> + st = track->stream = avformat_new_stream(s, NULL);
> + if (!st)
> + return AVERROR(ENOMEM);
> +
> if (track->audio.samplerate < 0 || track->audio.samplerate > INT_MAX ||
> isnan(track->audio.samplerate)) {
> av_log(matroska->ctx, AV_LOG_WARNING,
> @@ -1944,7 +1948,16 @@ static int matroska_parse_tracks(AVFormatContext *s)
> av_log(matroska->ctx, AV_LOG_ERROR,
> "Multiple combined encodings not supported");
> } else if (encodings_list->nb_elem == 1) {
> + AVMatroskaEncoding *side_data = (void*)av_stream_new_side_data(st,
> + AV_PKT_DATA_MATROSKA_ENCODING,
> + sizeof(AVMatroskaEncoding));
> + if (!side_data)
> + return AVERROR(ENOMEM);
> +
> + side_data->type = encodings[0].type;
> +
> if (encodings[0].type) {
> + side_data->algorithm = encodings[0].encryption.algo;
> if (encodings[0].encryption.key_id.size > 0) {
> /* Save the encryption key id to be stored later as a
> metadata tag. */
> @@ -1972,10 +1985,12 @@ static int matroska_parse_tracks(AVFormatContext *s)
> encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO &&
> #endif
> encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
> + side_data->algorithm = encodings[0].compression.algo;
> encodings[0].scope = 0;
> av_log(matroska->ctx, AV_LOG_ERROR,
> "Unsupported encoding type");
> } else if (track->codec_priv.size && encodings[0].scope & 2) {
> + side_data->algorithm = encodings[0].compression.algo;
> uint8_t *codec_priv = track->codec_priv.data;
> int ret = matroska_decode_buffer(&track->codec_priv.data,
> &track->codec_priv.size,
> @@ -1989,6 +2004,8 @@ static int matroska_parse_tracks(AVFormatContext *s)
>
> if (codec_priv != track->codec_priv.data)
> av_free(codec_priv);
> + } else {
> + side_data->algorithm = encodings[0].compression.algo;
> }
> }
>
> @@ -2000,12 +2017,6 @@ static int matroska_parse_tracks(AVFormatContext *s)
> }
> }
>
> - st = track->stream = avformat_new_stream(s, NULL);
> - if (!st) {
> - av_free(key_id_base64);
> - return AVERROR(ENOMEM);
> - }
> -
> if (key_id_base64) {
> /* export encryption key id as base64 metadata tag */
> av_dict_set(&st->metadata, "enc_key_id", key_id_base64, 0);
>
No comments on the actual implementation.
More information about the ffmpeg-devel
mailing list