diff options
Diffstat (limited to 'media/libnestegg/src/nestegg.c')
-rw-r--r-- | media/libnestegg/src/nestegg.c | 172 |
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; |