From cbf41b53598bc98e7d7de5a94bcdfe20d84024b4 Mon Sep 17 00:00:00 2001 From: Emeric Date: Mon, 26 Aug 2024 16:51:11 +0200 Subject: [PATCH] Work on colors --- mini_analyser/src/main.cpp | 6 +- mini_analyser/src/mainwindow_datas.cpp | 16 +++-- minivideo/src/bitstream_map.cpp | 70 +++++++++++++++++-- minivideo/src/demuxer/mkv/mkv_codec.cpp | 2 - minivideo/src/demuxer/mkv/mkv_struct.h | 2 +- minivideo/src/demuxer/mp4/mp4_stsd.cpp | 16 +---- minivideo/src/minivideo_avutils.h | 4 +- minivideo/src/minivideo_codecs.cpp | 26 ------- minivideo/src/minivideo_codecs.h | 2 - .../src/minivideo_codecs_private_struct.h | 8 ++- minivideo/src/minivideo_mediastream.h | 3 +- 11 files changed, 90 insertions(+), 65 deletions(-) diff --git a/mini_analyser/src/main.cpp b/mini_analyser/src/main.cpp index f338977..6b04071 100644 --- a/mini_analyser/src/main.cpp +++ b/mini_analyser/src/main.cpp @@ -46,11 +46,15 @@ */ int main(int argc, char *argv[]) { + // Arguments parsing /////////////////////////////////////////////////////// + + std::cout << GREEN "mini_analyser() arguments" RESET << std::endl; + bool cli_enabled = false; bool cli_details_enabled = false; + QStringList files; - std::cout << GREEN "mini_analyser() arguments" RESET << std::endl; for (int i = 1; i < argc; i++) { if (argv[i]) diff --git a/mini_analyser/src/mainwindow_datas.cpp b/mini_analyser/src/mainwindow_datas.cpp index 923d2c4..ca4dc98 100644 --- a/mini_analyser/src/mainwindow_datas.cpp +++ b/mini_analyser/src/mainwindow_datas.cpp @@ -780,9 +780,9 @@ int MainWindow::printAudioDetails() if (t->stream_size) { - uint64_t rawsize = t->sampling_rate * t->channel_count * (t->bit_per_sample / 8); + uint64_t rawsize = t->sampling_rate * t->channel_count * (t->bit_per_sample / 8.0); rawsize *= t->stream_duration_ms; - rawsize /= 1000; + rawsize /= 1000.0; uint64_t ratio = std::round(static_cast(rawsize) / static_cast(t->stream_size)); ui->label_audio_compression_ratio->setText(QString::number(ratio) + ":1"); @@ -1104,7 +1104,7 @@ int MainWindow::printVideoDetails() ui->label_video_par->setVisible(false); } - if (t->color_space > 0 && t->color_subsampling > 0) + if (t->color_space > 0 && t->chroma_subsampling > 0) { ui->label_50->setVisible(true); ui->label_60->setVisible(true); @@ -1126,7 +1126,7 @@ int MainWindow::printVideoDetails() else ui->label_video_color_space->setText("YCbCr (best guess)"); - ui->label_video_color_subsampling->setText(getChromaSubsamplingQString((ChromaSubSampling_e)t->color_subsampling)); + ui->label_video_color_subsampling->setText(getChromaSubsamplingQString((ChromaSubSampling_e)t->chroma_subsampling)); } else { @@ -1243,10 +1243,12 @@ int MainWindow::printVideoDetails() // Compression ratio if (t->stream_size) { - if (t->color_planes == 0) t->color_planes = 3; - if (t->color_depth == 0) t->color_depth = 8; + unsigned color_planes = t->color_planes; + unsigned color_depth = t->color_depth; + if (color_planes == 0) color_planes = 3; + if (color_depth == 0) color_depth = 8; - uint64_t rawsize = t->width * t->height * (t->color_depth / 8) * t->color_planes; + uint64_t rawsize = t->width * t->height * (color_depth / 8.0) * color_planes; rawsize *= t->sample_count; uint64_t ratio = std::round(static_cast(rawsize) / static_cast(t->stream_size)); diff --git a/minivideo/src/bitstream_map.cpp b/minivideo/src/bitstream_map.cpp index ce18a1f..cd9d3c5 100644 --- a/minivideo/src/bitstream_map.cpp +++ b/minivideo/src/bitstream_map.cpp @@ -571,15 +571,15 @@ bool computeCodecsSpecifics(MediaFile_t *media) // Chroma if (avcC->sps_array[0]->chroma_format_idc == 0) - track->color_subsampling = CHROMA_SS_400; + track->chroma_subsampling = CHROMA_SS_400; else if (avcC->sps_array[0]->chroma_format_idc == 1) - track->color_subsampling = CHROMA_SS_420; + track->chroma_subsampling = CHROMA_SS_420; else if (avcC->sps_array[0]->chroma_format_idc == 2) - track->color_subsampling = CHROMA_SS_422; + track->chroma_subsampling = CHROMA_SS_422; else if (avcC->sps_array[0]->chroma_format_idc == 3) - track->color_subsampling = CHROMA_SS_444; + track->chroma_subsampling = CHROMA_SS_444; else - track->color_subsampling = CHROMA_SS_420; + track->chroma_subsampling = CHROMA_SS_420; if (avcC->sps_array[0]->vui) { @@ -587,6 +587,16 @@ bool computeCodecsSpecifics(MediaFile_t *media) track->color_primaries = avcC->sps_array[0]->vui->colour_primaries; track->color_transfer = avcC->sps_array[0]->vui->transfer_characteristics; track->color_matrix = avcC->sps_array[0]->vui->matrix_coefficients; + + if (avcC->sps_array[0]->vui->chroma_loc_info_present_flag) + { + if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 0) track->chroma_location = CHROMA_LOC_LEFT; + else if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 1) track->chroma_location = CHROMA_LOC_CENTER; + else if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 2) track->chroma_location = CHROMA_LOC_TOPLEFT; + else if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 3) track->chroma_location = CHROMA_LOC_TOP; + else if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 4) track->chroma_location = CHROMA_LOC_BOTTOMLEFT; + else if (avcC->sps_array[0]->vui->chroma_sample_loc_type_top_field == 5) track->chroma_location = CHROMA_LOC_BOTTOM; + } } if (avcC->pps_count > 0 && avcC->pps_array[0]) @@ -634,6 +644,18 @@ bool computeCodecsSpecifics(MediaFile_t *media) track->color_depth = vpcC->bitDepth; track->color_range = vpcC->videoFullRangeFlag; + if (vpcC->chromaSubsampling == 0 || vpcC->chromaSubsampling == 1) + track->chroma_subsampling = CHROMA_SS_420; + else if (vpcC->chromaSubsampling == 2) + track->chroma_subsampling = CHROMA_SS_422; + else if (vpcC->chromaSubsampling == 3) + track->chroma_subsampling = CHROMA_SS_444; + + if (vpcC->chromaSubsampling == 1) + track->chroma_location = CHROMA_LOC_TOPLEFT; + else + track->chroma_location = CHROMA_LOC_LEFT; + track->color_primaries = vpcC->colourPrimaries; track->color_transfer = vpcC->transferCharacteristics; track->color_matrix = vpcC->matrixCoefficients; @@ -670,9 +692,43 @@ bool computeCodecsSpecifics(MediaFile_t *media) else if (av1C->seq_level_idx_0 == 22) track->video_level = 7.2; else if (av1C->seq_level_idx_0 == 23) track->video_level = 7.3; - if (av1C->high_bitdepth) track->color_depth = 10; - else if (av1C->twelve_bit) track->color_depth = 12; + if (av1C->twelve_bit) track->color_depth = 12; + else if (av1C->high_bitdepth) track->color_depth = 10; else track->color_depth = 8; + + if (av1C->chroma_subsampling_x == 0 && av1C->chroma_subsampling_y == 0 && av1C->monochrome == 0) + track->chroma_subsampling = CHROMA_SS_444; + else if (av1C->chroma_subsampling_x == 1 && av1C->chroma_subsampling_y == 0 && av1C->monochrome == 0) + track->chroma_subsampling = CHROMA_SS_422; + else if (av1C->chroma_subsampling_x == 1 && av1C->chroma_subsampling_y == 1 && av1C->monochrome == 0) + track->chroma_subsampling = CHROMA_SS_420; + else if (av1C->chroma_subsampling_x == 1 && av1C->chroma_subsampling_y == 1 && av1C->monochrome == 1) + track->chroma_subsampling = CHROMA_SS_400; + + if (av1C->chroma_sample_position == 1) + track->chroma_location = CHROMA_LOC_LEFT; + else if (av1C->chroma_sample_position == 2) + track->chroma_location = CHROMA_LOC_TOPLEFT; + } + + else if (track->stream_codec == CODEC_PRORES_422_PROXY || + track->stream_codec == CODEC_PRORES_422_LT || + track->stream_codec == CODEC_PRORES_422 || + track->stream_codec == CODEC_PRORES_422_HQ) + { + track->chroma_subsampling = CHROMA_SS_422; + } + else if (track->stream_codec == CODEC_PRORES_4444 || + track->stream_codec == CODEC_PRORES_4444_XQ) + { + track->chroma_subsampling = CHROMA_SS_444; + } + else if (track->stream_codec == CODEC_PRORES_RAW || + track->stream_codec == CODEC_PRORES_RAW_HQ) + { + // RAW variants are not using YUV pixel subsampling + track->chroma_subsampling = CHROMA_SS_UNKNOWN; + track->color_depth = 16; } } } diff --git a/minivideo/src/demuxer/mkv/mkv_codec.cpp b/minivideo/src/demuxer/mkv/mkv_codec.cpp index 5bac18e..75e720e 100644 --- a/minivideo/src/demuxer/mkv/mkv_codec.cpp +++ b/minivideo/src/demuxer/mkv/mkv_codec.cpp @@ -797,8 +797,6 @@ int parse_vpx_private(Bitstream_t *bitstr, mkv_track_t *track, mkv_t *mkv) TRACE_1(MP4, "> colourPrimaries: %u", track->vpcC->colourPrimaries); TRACE_1(MP4, "> transferCharacteristics: %u", track->vpcC->transferCharacteristics); TRACE_1(MP4, "> matrixCoefficients: %u", track->vpcC->matrixCoefficients); - - TRACE_1(MP4, "> codecIntializationDataSize: %u", track->vpcC->codecIntializationDataSize); #endif // ENABLE_DEBUG // xmlMapper diff --git a/minivideo/src/demuxer/mkv/mkv_struct.h b/minivideo/src/demuxer/mkv/mkv_struct.h index 065171c..6edd3d7 100644 --- a/minivideo/src/demuxer/mkv/mkv_struct.h +++ b/minivideo/src/demuxer/mkv/mkv_struct.h @@ -406,7 +406,7 @@ typedef struct mkv_track_t std::vector sample_vector; // Video specific parameters - unsigned int color_depth = 8; + unsigned int color_depth = 0; unsigned int color_range = 0; unsigned int color_space = 0; unsigned int color_primaries = 0; diff --git a/minivideo/src/demuxer/mp4/mp4_stsd.cpp b/minivideo/src/demuxer/mp4/mp4_stsd.cpp index 561435a..d5d39bd 100644 --- a/minivideo/src/demuxer/mp4/mp4_stsd.cpp +++ b/minivideo/src/demuxer/mp4/mp4_stsd.cpp @@ -1619,8 +1619,8 @@ int parse_vpcC(Bitstream_t *bitstr, Mp4Box_t *box_header, Mp4Track_t *track, Mp4 track->vpcC->transferCharacteristics = read_bits(bitstr, 8); track->vpcC->matrixCoefficients = read_bits(bitstr, 8); - track->vpcC->codecIntializationDataSize = read_bits(bitstr, 16); - if (track->vpcC->codecIntializationDataSize > 0) + int codecIntializationDataSize = read_bits(bitstr, 16); + if (codecIntializationDataSize > 0) { // Note: must be 0 for VP8 and VP9 } @@ -1634,12 +1634,6 @@ int parse_vpcC(Bitstream_t *bitstr, Mp4Box_t *box_header, Mp4Track_t *track, Mp4 TRACE_1(MP4, "> colourPrimaries: %u", track->vpcC->colourPrimaries); TRACE_1(MP4, "> transferCharacteristics: %u", track->vpcC->transferCharacteristics); TRACE_1(MP4, "> matrixCoefficients: %u", track->vpcC->matrixCoefficients); - - TRACE_1(MP4, "> codecIntializationDataSize: %u", track->vpcC->codecIntializationDataSize); - if (track->vpcC->codecIntializationDataSize) - { - // TODO - } #endif // ENABLE_DEBUG // xmlMapper @@ -1653,12 +1647,6 @@ int parse_vpcC(Bitstream_t *bitstr, Mp4Box_t *box_header, Mp4Track_t *track, Mp4 fprintf(mp4->xml, " %u\n", track->vpcC->colourPrimaries); fprintf(mp4->xml, " %u\n", track->vpcC->transferCharacteristics); fprintf(mp4->xml, " %u\n", track->vpcC->matrixCoefficients); - - fprintf(mp4->xml, " %u\n", track->vpcC->codecIntializationDataSize); - if (track->vpcC->codecIntializationDataSize) - { - // TODO - } fprintf(mp4->xml, " \n"); } diff --git a/minivideo/src/minivideo_avutils.h b/minivideo/src/minivideo_avutils.h index 2b743ee..f352f37 100644 --- a/minivideo/src/minivideo_avutils.h +++ b/minivideo/src/minivideo_avutils.h @@ -191,9 +191,9 @@ typedef enum ChromaLocation_e { CHROMA_LOC_UNKNOWN = 0, //!< Unknown chroma location - CHROMA_LOC_LEFT = 1, //!< + CHROMA_LOC_LEFT = 1, //!< vertical CHROMA_LOC_CENTER = 2, - CHROMA_LOC_TOPLEFT = 3, + CHROMA_LOC_TOPLEFT = 3, //!< colocated CHROMA_LOC_TOP = 4, CHROMA_LOC_BOTTOMLEFT = 5, CHROMA_LOC_BOTTOM = 6, diff --git a/minivideo/src/minivideo_codecs.cpp b/minivideo/src/minivideo_codecs.cpp index 954a6b5..def1c10 100644 --- a/minivideo/src/minivideo_codecs.cpp +++ b/minivideo/src/minivideo_codecs.cpp @@ -745,32 +745,6 @@ const char *getCodecString(const StreamType_e type, const Codecs_e codec, const /* ************************************************************************** */ -const char *getPictureString(const Pictures_e picture, const bool long_description) -{ - switch (picture) - { - case PICTURE_BMP: - return "BMP"; - case PICTURE_JPG: - return "JPG"; - case PICTURE_PNG: - return "PNG"; - case PICTURE_WEBP: - return "WebP"; - case PICTURE_TGA: - return "TGA"; - case PICTURE_YUV444: - return "YCbCr 4:4:4"; - case PICTURE_YUV420: - return "YCbCr 4:2:0"; - - default: - return ""; - } -} - -/* ************************************************************************** */ - const char *getCodecProfileString(const CodecProfiles_e profile, const bool long_description) { switch (profile) diff --git a/minivideo/src/minivideo_codecs.h b/minivideo/src/minivideo_codecs.h index 9a7189a..19cb101 100644 --- a/minivideo/src/minivideo_codecs.h +++ b/minivideo/src/minivideo_codecs.h @@ -430,8 +430,6 @@ CodecProfiles_e getH266CodecProfile(const unsigned profil_idc); minivideo_EXPORT const char *getCodecString(const StreamType_e type, const Codecs_e codec, const bool long_description = false); minivideo_EXPORT const char *getCodecProfileString(const CodecProfiles_e profile, const bool long_description = false); -minivideo_EXPORT const char *getPictureString(const Pictures_e picture, const bool long_description = false); - /* ************************************************************************** */ minivideo_EXPORT const char *getScanModeString(const ScanType_e mode); diff --git a/minivideo/src/minivideo_codecs_private_struct.h b/minivideo/src/minivideo_codecs_private_struct.h index 777e618..0a1784e 100644 --- a/minivideo/src/minivideo_codecs_private_struct.h +++ b/minivideo/src/minivideo_codecs_private_struct.h @@ -109,6 +109,9 @@ typedef struct codecprivate_vvcC_t /* ************************************************************************** */ +/*! + * https://www.webmproject.org/vp9/mp4/ + */ typedef struct codecprivate_vpcC_t { uint8_t profile; @@ -120,12 +123,13 @@ typedef struct codecprivate_vpcC_t uint8_t transferCharacteristics; uint8_t matrixCoefficients; - uint16_t codecIntializationDataSize; - } codecprivate_vpcC_t; /* ************************************************************************** */ +/*! + * https://aomediacodec.github.io/av1-isobmff/ + */ typedef struct codecprivate_av1C_t { bool marker; diff --git a/minivideo/src/minivideo_mediastream.h b/minivideo/src/minivideo_mediastream.h index cb8b2ad..4eede07 100644 --- a/minivideo/src/minivideo_mediastream.h +++ b/minivideo/src/minivideo_mediastream.h @@ -105,9 +105,10 @@ typedef struct MediaStream_t FramerateMode_e framerate_mode; //!< Framerate mode unsigned int color_planes; //!< Number of encoded planes (ex: 1 for monochrome, 3 for YUV or 4 for RGBA) - unsigned int color_subsampling; //!< Chroma sub-sampling unsigned int color_depth; //!< Color resolution per channel unsigned int color_range; //!< Colors are in restricted or full range + unsigned int chroma_subsampling; //!< Chroma sub-sampling + unsigned int chroma_location; //!< Chroma location unsigned int color_space; //!< Internal color encoding unsigned int color_primaries; //!< Color primaries unsigned int color_transfer; //!< Color transfer function