summaryrefslogtreecommitdiff
path: root/media/libnestegg/src/nestegg.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libnestegg/src/nestegg.c')
-rw-r--r--media/libnestegg/src/nestegg.c172
1 files changed, 154 insertions, 18 deletions
diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c
index 051bc50faf..ae7c73d9d2 100644
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -88,6 +88,7 @@
#define ID_PIXEL_CROP_RIGHT 0x54dd
#define ID_DISPLAY_WIDTH 0x54b0
#define ID_DISPLAY_HEIGHT 0x54ba
+#define ID_COLOUR 0x55b0
/* Audio Elements */
#define ID_AUDIO 0xe1
@@ -116,6 +117,25 @@
#define ID_CONTENT_ENC_AES_SETTINGS 0x47e7
#define ID_AES_SETTINGS_CIPHER_MODE 0x47e8
+/* Colour Elements */
+#define ID_MATRIX_COEFFICIENTS 0x55b1
+#define ID_RANGE 0x55b9
+#define ID_TRANSFER_CHARACTERISTICS 0x55ba
+#define ID_PRIMARIES 0x55bb
+#define ID_MASTERING_METADATA 0x55d0
+
+/* MasteringMetadata Elements */
+#define ID_PRIMARY_R_CHROMATICITY_X 0x55d1
+#define ID_PRIMARY_R_CHROMATICITY_Y 0x55d2
+#define ID_PRIMARY_G_CHROMATICITY_X 0x55d3
+#define ID_PRIMARY_G_CHROMATICITY_Y 0x55d4
+#define ID_PRIMARY_B_CHROMATICITY_X 0x55d5
+#define ID_PRIMARY_B_CHROMATICITY_Y 0x55d6
+#define ID_WHITE_POINT_CHROMATICITY_X 0x55d7
+#define ID_WHITE_POINT_CHROMATICITY_Y 0x55d8
+#define ID_LUMINANCE_MAX 0x55d9
+#define ID_LUMINANCE_MIN 0x55da
+
/* EBML Types */
enum ebml_type_enum {
TYPE_UNKNOWN,
@@ -236,6 +256,27 @@ struct info {
struct ebml_type duration;
};
+struct mastering_metadata {
+ struct ebml_type primary_r_chromacity_x;
+ struct ebml_type primary_r_chromacity_y;
+ struct ebml_type primary_g_chromacity_x;
+ struct ebml_type primary_g_chromacity_y;
+ struct ebml_type primary_b_chromacity_x;
+ struct ebml_type primary_b_chromacity_y;
+ struct ebml_type white_point_chromaticity_x;
+ struct ebml_type white_point_chromaticity_y;
+ struct ebml_type luminance_max;
+ struct ebml_type luminance_min;
+};
+
+struct colour {
+ struct ebml_type matrix_coefficients;
+ struct ebml_type range;
+ struct ebml_type transfer_characteristics;
+ struct ebml_type primaries;
+ struct mastering_metadata mastering_metadata;
+};
+
struct video {
struct ebml_type stereo_mode;
struct ebml_type alpha_mode;
@@ -247,6 +288,7 @@ struct video {
struct ebml_type pixel_crop_right;
struct ebml_type display_width;
struct ebml_type display_height;
+ struct colour colour;
};
struct audio {
@@ -454,6 +496,29 @@ static struct ebml_element_desc ne_info_elements[] = {
E_LAST
};
+static struct ebml_element_desc ne_mastering_metadata_elements[] = {
+ E_FIELD(ID_PRIMARY_R_CHROMATICITY_X, TYPE_FLOAT, struct mastering_metadata, primary_r_chromacity_x),
+ E_FIELD(ID_PRIMARY_R_CHROMATICITY_Y, TYPE_FLOAT, struct mastering_metadata, primary_r_chromacity_y),
+ E_FIELD(ID_PRIMARY_G_CHROMATICITY_X, TYPE_FLOAT, struct mastering_metadata, primary_g_chromacity_x),
+ E_FIELD(ID_PRIMARY_G_CHROMATICITY_Y, TYPE_FLOAT, struct mastering_metadata, primary_g_chromacity_y),
+ E_FIELD(ID_PRIMARY_B_CHROMATICITY_X, TYPE_FLOAT, struct mastering_metadata, primary_b_chromacity_x),
+ E_FIELD(ID_PRIMARY_B_CHROMATICITY_Y, TYPE_FLOAT, struct mastering_metadata, primary_b_chromacity_y),
+ E_FIELD(ID_WHITE_POINT_CHROMATICITY_X, TYPE_FLOAT, struct mastering_metadata, white_point_chromaticity_x),
+ E_FIELD(ID_WHITE_POINT_CHROMATICITY_Y, TYPE_FLOAT, struct mastering_metadata, white_point_chromaticity_y),
+ E_FIELD(ID_LUMINANCE_MAX, TYPE_FLOAT, struct mastering_metadata, luminance_max),
+ E_FIELD(ID_LUMINANCE_MIN, TYPE_FLOAT, struct mastering_metadata, luminance_min),
+ E_LAST
+};
+
+static struct ebml_element_desc ne_colour_elements[] = {
+ E_FIELD(ID_MATRIX_COEFFICIENTS, TYPE_UINT, struct colour, matrix_coefficients),
+ E_FIELD(ID_RANGE, TYPE_UINT, struct colour, range),
+ E_FIELD(ID_TRANSFER_CHARACTERISTICS, TYPE_UINT, struct colour, transfer_characteristics),
+ E_FIELD(ID_PRIMARIES, TYPE_UINT, struct colour, primaries),
+ E_SINGLE_MASTER(ID_MASTERING_METADATA, TYPE_MASTER, struct colour, mastering_metadata),
+ E_LAST
+};
+
static struct ebml_element_desc ne_video_elements[] = {
E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode),
E_FIELD(ID_ALPHA_MODE, TYPE_UINT, struct video, alpha_mode),
@@ -465,6 +530,7 @@ static struct ebml_element_desc ne_video_elements[] = {
E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right),
E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width),
E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height),
+ E_SINGLE_MASTER(ID_COLOUR, TYPE_MASTER, struct video, colour),
E_LAST
};
@@ -770,7 +836,15 @@ ne_read_float(nestegg_io * io, double * val, uint64_t length)
{
union {
uint64_t u;
- float f;
+ struct {
+#if defined(__FLOAT_WORD_ORDER__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
+ uint32_t _pad;
+ float f;
+#else
+ float f;
+ uint32_t _pad;
+#endif
+ } f;
double d;
} value;
int r;
@@ -782,7 +856,7 @@ ne_read_float(nestegg_io * io, double * val, uint64_t length)
if (r != 1)
return r;
if (length == 4)
- *val = value.f;
+ *val = value.f.f;
else
*val = value.d;
return 1;
@@ -2062,7 +2136,10 @@ ne_match_webm(nestegg_io io, int64_t max_offset)
return 0;
}
- ne_ctx_push(ctx, ne_top_level_elements, ctx);
+ if (ne_ctx_push(ctx, ne_top_level_elements, ctx) < 0) {
+ nestegg_destroy(ctx);
+ return -1;
+ }
/* we don't check the return value of ne_parse, that might fail because
max_offset is not on a valid element end point. We only want to check
@@ -2118,7 +2195,10 @@ nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t ma
ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx);
- ne_ctx_push(ctx, ne_top_level_elements, ctx);
+ if (ne_ctx_push(ctx, ne_top_level_elements, ctx) < 0) {
+ nestegg_destroy(ctx);
+ return -1;
+ }
r = ne_parse(ctx, NULL, max_offset);
while (ctx->ancestor)
@@ -2178,7 +2258,8 @@ void
nestegg_destroy(nestegg * ctx)
{
assert(ctx->ancestor == NULL);
- ne_pool_destroy(ctx->alloc_pool);
+ if (ctx->alloc_pool)
+ ne_pool_destroy(ctx->alloc_pool);
free(ctx->io);
free(ctx);
}
@@ -2366,10 +2447,10 @@ nestegg_track_type(nestegg * ctx, unsigned int track)
if (ne_get_uint(entry->type, &type) != 0)
return -1;
- if (type & TRACK_TYPE_VIDEO)
+ if (type == TRACK_TYPE_VIDEO)
return NESTEGG_TRACK_VIDEO;
- if (type & TRACK_TYPE_AUDIO)
+ if (type == TRACK_TYPE_AUDIO)
return NESTEGG_TRACK_AUDIO;
return NESTEGG_TRACK_UNKNOWN;
@@ -2537,6 +2618,7 @@ nestegg_track_video_params(nestegg * ctx, unsigned int track,
{
struct track_entry * entry;
uint64_t value;
+ double fvalue;
memset(params, 0, sizeof(*params));
@@ -2589,6 +2671,62 @@ nestegg_track_video_params(nestegg * ctx, unsigned int track,
ne_get_uint(entry->video.display_height, &value);
params->display_height = value;
+ value = 2;
+ ne_get_uint(entry->video.colour.matrix_coefficients, &value);
+ params->matrix_coefficients = value;
+
+ value = 0;
+ ne_get_uint(entry->video.colour.range, &value);
+ params->range = value;
+
+ value = 2;
+ ne_get_uint(entry->video.colour.transfer_characteristics, &value);
+ params->transfer_characteristics = value;
+
+ value = 2;
+ ne_get_uint(entry->video.colour.primaries, &value);
+ params->primaries = value;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_r_chromacity_x, &fvalue);
+ params->primary_r_chromacity_x = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_r_chromacity_y, &fvalue);
+ params->primary_r_chromacity_y = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_g_chromacity_x, &fvalue);
+ params->primary_g_chromacity_x = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_g_chromacity_y, &fvalue);
+ params->primary_g_chromacity_y = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_b_chromacity_x, &fvalue);
+ params->primary_b_chromacity_x = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.primary_b_chromacity_y, &fvalue);
+ params->primary_b_chromacity_y = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.white_point_chromaticity_x, &fvalue);
+ params->white_point_chromaticity_x = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.white_point_chromaticity_y, &fvalue);
+ params->white_point_chromaticity_y = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.luminance_max, &fvalue);
+ params->luminance_max = fvalue;
+
+ fvalue = strtod("NaN", NULL);
+ ne_get_float(entry->video.colour.mastering_metadata.luminance_min, &fvalue);
+ params->luminance_min = fvalue;
+
return 0;
}
@@ -2783,20 +2921,18 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
if (r != 1)
return r;
- /* Some files have a crc32 element, since it also has to be first it
- conflicts with the timecode spec. Just ignore it */
+ /* Matroska may place a CRC32 before the Timecode. Skip and continue parsing. */
if (id == ID_CRC32) {
- ctx->log(ctx, NESTEGG_LOG_DEBUG,
- "read_packet: skipping crc element in a cluster");
- r = ne_io_read_skip(ctx->io, size);
- if (r != 1)
- return r;
- r = ne_read_element(ctx, &id, &size);
- if (r != 1)
- return r;
+ r = ne_io_read_skip(ctx->io, size);
+ if (r != 1)
+ return r;
+
+ r = ne_read_element(ctx, &id, &size);
+ if (r != 1)
+ return r;
}
- /* Timecode must be the first element in a Cluster, per spec. */
+ /* Timecode must be the first element in a Cluster, per WebM spec. */
if (id != ID_TIMECODE)
return -1;