[FFmpeg-devel] [PATCH 2/5] avformat/matroskadec: Parse dvcC/dvvC block additional mapping
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Thu Sep 23 04:56:23 EEST 2021
quietvoid:
> The parsing was implemented in isom, for the unification of
> the mov/mpegts DOVI parsing into one function, in a later patch.
> Most of the implementation was done by Plex developers.
>
> Signed-off-by: quietvoid <tcChlisop0 at gmail.com>
> ---
> libavformat/isom.c | 51 +++++++++++++++++++++++++++++++++++++++
> libavformat/isom.h | 5 ++++
> libavformat/matroskadec.c | 13 ++++++++++
> 3 files changed, 69 insertions(+)
>
> diff --git a/libavformat/isom.c b/libavformat/isom.c
> index 4df5440023..80a8f4d7b0 100644
> --- a/libavformat/isom.c
> +++ b/libavformat/isom.c
> @@ -430,3 +430,54 @@ void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
> }
> avio_wb32(pb, 0); // mNumberChannelDescriptions
> }
> +
> +int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb)
> +{
> + AVDOVIDecoderConfigurationRecord *dovi;
> + size_t dovi_size;
> + int ret;
> +
> + if (gb->size_in_bits < 32)
> + return AVERROR_INVALIDDATA;
> +
> + dovi = av_dovi_alloc(&dovi_size);
> + if (!dovi)
> + return AVERROR(ENOMEM);
> +
> + dovi->dv_version_major = get_bits(gb, 8);
> + dovi->dv_version_minor = get_bits(gb, 8);
> +
> + dovi->dv_profile = get_bits(gb, 7);
> + dovi->dv_level = get_bits(gb, 6);
> + dovi->rpu_present_flag = get_bits1(gb);
> + dovi->el_present_flag = get_bits1(gb);
> + dovi->bl_present_flag = get_bits1(gb);
> +
> + // Has enough remaining data
> + if (gb->size_in_bits >= 36) {
> + dovi->dv_bl_signal_compatibility_id = get_bits(gb, 4);
> + } else {
> + // 0 stands for None
> + // Dolby Vision V1.2.93 profiles and levels
> + dovi->dv_bl_signal_compatibility_id = 0;
> + }
> +
> + ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
> + (uint8_t *)dovi, dovi_size);
> + if (ret < 0) {
> + av_free(dovi);
> + return ret;
> + }
> +
> + av_log(s, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, "
> + "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
> + dovi->dv_version_major, dovi->dv_version_minor,
> + dovi->dv_profile, dovi->dv_level,
> + dovi->rpu_present_flag,
> + dovi->el_present_flag,
> + dovi->bl_present_flag,
> + dovi->dv_bl_signal_compatibility_id
> + );
> +
> + return 0;
> +}
The Matroska demuxer currently needs nothing from isom.c and so has no
Makefile dependency for it. So a build with only the Matroska demuxer
enabled will fail. I'd like to avoid a dependency on the unused parts of
isom.c (isom.c calls some avpriv functions from libavcodec and I'd
really like to avoid this unnecessary dependency), so can you move this
into a new file (say isom_dovi.c or so)?
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index 34a58c79b7..44bd839852 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -27,6 +27,9 @@
> #include <stddef.h>
> #include <stdint.h>
>
> +#include "libavcodec/get_bits.h"
> +
> +#include "libavutil/dovi_meta.h"
> #include "libavutil/encryption_info.h"
> #include "libavutil/mastering_display_metadata.h"
> #include "libavutil/spherical.h"
> @@ -390,4 +393,6 @@ static inline enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
> #define MOV_ISMV_TTML_TAG MKTAG('d', 'f', 'x', 'p')
> #define MOV_MP4_TTML_TAG MKTAG('s', 't', 'p', 'p')
>
> +int ff_mov_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, GetBitContext *gb);
> +
> #endif /* AVFORMAT_ISOM_H */
> diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
> index 8ae553953d..4633067d48 100644
> --- a/libavformat/matroskadec.c
> +++ b/libavformat/matroskadec.c
> @@ -2323,6 +2323,14 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track,
> return 0;
> }
>
> +static int mkv_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const MatroskaTrack *track,
> + EbmlBin *bin)
> +{
> + GetBitContext gb;
> + init_get_bits8(&gb, bin->data, bin->size);
I do not see why the caller has to open the GetBitContext instead of
passing a simple buffer. All three prospective users of
ff_mov_parse_dvcc_dvvc have a buffer, but not a GetBitContext to read it.
Furthermore, using a GetBitContext for such a trivial parsing might
backfire: Not all buffers here are padded (the wtvdec demuxer also uses
it via ff_parse_mpeg2_descriptor), so it seems best to just parse it
without a GetBitContext in the way mov already does.
> + return ff_mov_parse_dvcc_dvvc(s, st, &gb);
> +}
> +
> static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track)
> {
> int i, ret;
> @@ -2333,6 +2341,11 @@ static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, c
> MatroskaBlockAdditionMapping *mapping = &mappings[i];
>
> switch (mapping->type) {
> + case MKBETAG('d','v','c','C'):
> + case MKBETAG('d','v','v','C'):
> + if ((ret = mkv_parse_dvcc_dvvc(s, st, track, &mapping->extradata)) < 0)
> + return ret;
> + break;
> default:
> av_log(s, AV_LOG_DEBUG,
> "Unknown block additional mapping type %i, value %i, name \"%s\"\n",
>
More information about the ffmpeg-devel
mailing list