jpeg2000parse: parse RSIZ capabilities and put profile/level into the caps

The RSIZ capabilities tag stores the JPEG 2000 profile. In the case of
broadcast profiles, it also stores the broadcast main level, which
specifies the bit rate.

https://bugzilla.gnome.org/show_bug.cgi?id=782337
This commit is contained in:
Aaron Boxer 2017-05-12 15:28:46 -04:00 committed by Sebastian Dröge
parent 87cb9fa49e
commit 9ec2b7ce13
2 changed files with 150 additions and 7 deletions

View file

@ -25,6 +25,35 @@
#include "gstjpeg2000parse.h"
#include <gst/base/base.h>
/* Not used at the moment
static gboolean gst_jpeg2000_parse_is_cinema(guint16 rsiz) {
return ((rsiz >= GST_JPEG2000_PARSE_PROFILE_CINEMA_2K) && (rsiz <= GST_JPEG2000_PARSE_PROFILE_CINEMA_S4K));
}
static gboolean gst_jpeg2000_parse_is_storage(guint16 rsiz) {
return (rsiz == GST_JPEG2000_PARSE_PROFILE_CINEMA_LTS);
}
*/
static gboolean
gst_jpeg2000_parse_is_broadcast (guint16 rsiz)
{
return ((rsiz >= GST_JPEG2000_PARSE_PROFILE_BC_SINGLE) &&
(rsiz <= ((GST_JPEG2000_PARSE_PROFILE_BC_MULTI_R) | (0x000b)))
&& ((rsiz & (~GST_JPEG2000_PARSE_PROFILE_BC_MASK)) == 0));
}
static gboolean
gst_jpeg2000_parse_is_imf (guint16 rsiz)
{
return ((rsiz >= GST_JPEG2000_PARSE_PROFILE_IMF_2K)
&& (rsiz <= ((GST_JPEG2000_PARSE_PROFILE_IMF_8K_R) | (0x009b))));
}
static gboolean
gst_jpeg2000_parse_is_part_2 (guint16 rsiz)
{
return (rsiz & GST_JPEG2000_PARSE_PROFILE_PART2);
}
static void
@ -67,11 +96,13 @@ static GstStaticPadTemplate srctemplate =
" width = (int)[1, MAX], height = (int)[1, MAX],"
GST_JPEG2000_SAMPLING_LIST ","
GST_JPEG2000_COLORSPACE_LIST ","
" profile = (int)[0, 49151],"
" parsed = (boolean) true;"
"image/x-j2c,"
" width = (int)[1, MAX], height = (int)[1, MAX],"
GST_JPEG2000_SAMPLING_LIST ","
GST_JPEG2000_COLORSPACE_LIST "," " parsed = (boolean) true")
GST_JPEG2000_COLORSPACE_LIST ","
" profile = (int)[0, 49151]," " parsed = (boolean) true")
);
static GstStaticPadTemplate sinktemplate =
@ -272,6 +303,11 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse,
guint8 dx[GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS];
guint8 dy[GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS];
guint16 numcomps;
guint16 capabilities = 0;
guint16 profile = 0;
gboolean validate_main_level = FALSE;
guint8 main_level = 0;
guint8 sub_level = 0;
guint16 compno;
GstJPEG2000Sampling parsed_sampling = GST_JPEG2000_SAMPLING_NONE;
const gchar *sink_sampling_string = NULL;
@ -361,10 +397,47 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse,
goto beach;
}
/* 2 to skip marker size, and another 2 to skip rsiz field */
if (!gst_byte_reader_skip (&reader, num_prefix_bytes + 2 + 2))
/* 2 to skip marker size */
if (!gst_byte_reader_skip (&reader, num_prefix_bytes + 2))
goto beach;
if (!gst_byte_reader_get_uint16_be (&reader, &capabilities))
goto beach;
profile = capabilities & GST_JPEG2000_PARSE_PROFILE_MASK;
if (!gst_jpeg2000_parse_is_part_2 (capabilities)) {
if ((profile > GST_JPEG2000_PARSE_PROFILE_CINEMA_LTS)
&& !gst_jpeg2000_parse_is_broadcast (profile)
&& !gst_jpeg2000_parse_is_imf (profile)) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Unrecognized JPEG 2000 profile %d", profile));
ret = GST_FLOW_ERROR;
goto beach;
}
if (gst_jpeg2000_parse_is_broadcast (profile)) {
main_level = capabilities & 0xF;
validate_main_level = TRUE;
} else if (gst_jpeg2000_parse_is_imf (profile)) {
main_level = capabilities & 0xF;
validate_main_level = TRUE;
sub_level = (capabilities >> 4) & 0xF;
if (sub_level > 9) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Sub level %d is invalid", sub_level));
ret = GST_FLOW_ERROR;
goto beach;
}
}
if (validate_main_level && main_level > 11) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Main level %d is invalid", main_level));
ret = GST_FLOW_ERROR;
goto beach;
}
}
if (!gst_byte_reader_get_uint32_be (&reader, &x1))
goto beach;
@ -560,10 +633,23 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse,
src_caps =
gst_caps_new_simple (media_type_from_codec_format
(jpeg2000parse->codec_format), "width", G_TYPE_INT, width, "height",
G_TYPE_INT, height, "colorspace", G_TYPE_STRING,
(jpeg2000parse->codec_format),
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
"colorspace", G_TYPE_STRING,
gst_jpeg2000_colorspace_to_string (colorspace), "sampling",
G_TYPE_STRING, gst_jpeg2000_sampling_to_string (source_sampling), NULL);
G_TYPE_STRING, gst_jpeg2000_sampling_to_string (source_sampling),
"profile", G_TYPE_UINT, profile, NULL);
if (gst_jpeg2000_parse_is_broadcast (capabilities)
|| gst_jpeg2000_parse_is_imf (capabilities)) {
gst_caps_set_simple (src_caps, "main-level", G_TYPE_UINT, main_level,
NULL);
if (gst_jpeg2000_parse_is_imf (capabilities)) {
gst_caps_set_simple (src_caps, "sub-level", G_TYPE_UINT, sub_level,
NULL);
}
}
if (gst_structure_get_fraction (current_caps_struct, "framerate", &fr_num,
&fr_denom)) {

View file

@ -42,7 +42,64 @@ G_BEGIN_DECLS
typedef struct _GstJPEG2000Parse GstJPEG2000Parse;
typedef struct _GstJPEG2000ParseClass GstJPEG2000ParseClass;
#define GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS 4
/**
* JPEG 2000 Profiles (stored in rsiz/capabilities field in code stream header)
* See Table A.10 from 15444-1 (updated in various AMDs)
*
* For broadcast profiles, the GST_JPEG2000_PARSE_PROFILE_BC_XXXX profile value must be combined with the target
* main level (3-0 LSBs, with value between 0 and 11).
* Example:
* capabilities GST_JPEG2000_PARSE_PROFILE_BC_MULTI | 0x0005 (in this case, main level equals 5)
*
* For IMF profiles, the GST_JPEG2000_PARSE_PROFILE_IMF_XXXX profile value must be combined with the target main level
* (3-0 LSBs, with value between 0 and 11), and target sub level (7-4 LSBs, with value between 0 and 9).
* Example:
* capabilities GST_JPEG2000_PARSE_PROFILE_IMF_2K | 0x0040 | 0x0005 (in this case, main level equals 5 and sub level equals 4)
*
*
* Broadcast main level (15444-1 AMD4,AMD8)
*
* Note: Mbit/s == 10^6 bits/s; Msamples/s == 10^6 samples/s
*
* Level 0: no max rate
* Level 1: 200 Mbits/s, 65 Msamples/s
* Level 2: 200 Mbits/s, 130 Msamples/s
* Level 3: 200 Mbits/s, 195 Msamples/s
* Level 4: 400 Mbits/s, 260 Msamples/s
* Level 5: 800Mbits/s, 520 Msamples/s
* Level >= 6: 2^(Level-6) * 1600 Mbits/s, 2^(Level-6) * 1200 Msamples/s
*
* Broadcast tiling
*
* Either single-tile or multi-tile. Multi-tile only permits
* 1 or 4 tiles per frame, where multiple tiles have identical
* sizes, and are configured in either 2x2 or 1x4 layout.
*
* */
#define GST_JPEG2000_PARSE_PROFILE_NONE 0x0000 /** no profile - defined in 15444-1 */
#define GST_JPEG2000_PARSE_PROFILE_0 0x0001 /** Profile 0 - defined in 15444-1,Table A.45 */
#define GST_JPEG2000_PARSE_PROFILE_1 0x0002 /** Profile 1 - defined in 15444-1,Table A.45 */
#define GST_JPEG2000_PARSE_PROFILE_CINEMA_2K 0x0003 /** 2K Cinema profile - defined in 15444-1 AMD1 */
#define GST_JPEG2000_PARSE_PROFILE_CINEMA_4K 0x0004 /** 4K Cinema profile - defined in 15444-1 AMD1 */
#define GST_JPEG2000_PARSE_PROFILE_CINEMA_S2K 0x0005 /** Scalable 2K Cinema profile - defined in 15444-1 AMD2 */
#define GST_JPEG2000_PARSE_PROFILE_CINEMA_S4K 0x0006 /** Scalable 4K Cinema profile - defined in 15444-1 AMD2 */
#define GST_JPEG2000_PARSE_PROFILE_CINEMA_LTS 0x0007/** Long Term Storage Cinema profile - defined in 15444-1 AMD2 */
#define GST_JPEG2000_PARSE_PROFILE_BC_SINGLE 0x0100 /** Single Tile Broadcast profile - defined in 15444-1 AMD3 */
#define GST_JPEG2000_PARSE_PROFILE_BC_MULTI 0x0200 /** Multi Tile Broadcast profile - defined in 15444-1 AMD3 */
#define GST_JPEG2000_PARSE_PROFILE_BC_MULTI_R 0x0300 /** Multi Tile Reversible Broadcast profile - defined in 15444-1 AMD3 */
#define GST_JPEG2000_PARSE_PROFILE_BC_MASK 0x0F0F /** Mask for broadcast profile, including main level */
#define GST_JPEG2000_PARSE_PROFILE_IMF_2K 0x0400 /** 2K Single Tile Lossy IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_IMF_4K 0x0401 /** 4K Single Tile Lossy IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_IMF_8K 0x0402 /** 8K Single Tile Lossy IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_IMF_2K_R 0x0403 /** 2K Single/Multi Tile Reversible IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_IMF_4K_R 0x0800 /** 4K Single/Multi Tile Reversible IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_IMF_8K_R 0x0801 /** 8K Single/Multi Tile Reversible IMF profile - defined in 15444-1 AMD 8 */
#define GST_JPEG2000_PARSE_PROFILE_MASK 0xBFFF /** Mask for profile bits */
#define GST_JPEG2000_PARSE_PROFILE_PART2 0x8000 /** At least 1 extension defined in 15444-2 (Part-2) */
#define GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS 4
typedef enum
{