From: Gwenole Beauchesne Date: Thu, 21 Jun 2012 14:06:47 +0000 (+0200) Subject: codecparsers: jpeg: track valid quantization and Huffman tables. X-Git-Tag: 0.4.0~153 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=326a229636a3444d08a933e523683d9fcb368bcb;p=platform%2Fupstream%2Fgstreamer-vaapi.git codecparsers: jpeg: track valid quantization and Huffman tables. Add valid flag to GstJpegQuantTable and GstJpegHuffmanTable so that to determine whether a table actually changed since the last user synchronization point. That way, this makes it possible for some hardware accelerated decoding solution to upload only those tables that changed. --- diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index f7a7c32..35187c4 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -101,37 +101,39 @@ static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker); /* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ -/* only for 8-bit per sample image*/ -static const GstJpegQuantTable -default_quant_tables_zigzag[GST_JPEG_MAX_SCAN_COMPONENTS] = { - /* luma */ - {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 } }, - /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, - /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 } }, - {0, } +/* only for 8-bit per sample image */ +static const GstJpegQuantTables +default_quant_tables_zigzag = { + .quant_tables = { + /* luma */ + {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 }, TRUE }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + /* chroma */ + {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + {0, } + } }; /* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ @@ -141,30 +143,33 @@ GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tabl */ static const GstJpegHuffmanTables default_huf_tables = { - { + .dc_tables = { /* DC luma */ { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, /* DC chroma */ { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, /* DC chroma */ { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b } + 0x08, 0x09, 0x0a, 0x0b }, + TRUE }, { { 0x0 }, { 0x0 } } }, - { + .ac_tables = { /* AC luma */ { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, @@ -188,7 +193,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa} + 0xf9, 0xfa}, + TRUE }, /* AC chroma */ { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, @@ -213,7 +219,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } + 0xf9, 0xfa }, + TRUE }, /* AC chroma */ { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, @@ -238,7 +245,8 @@ GstJpegHuffmanTables default_huf_tables = { 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa } + 0xf9, 0xfa }, + TRUE }, { { 0x00 }, { 0x00 } @@ -373,6 +381,7 @@ gst_jpeg_parse_huffman_table ( for (i = 0; i < 16; i++) value_count += huf_table->huf_bits[i]; READ_BYTES (&bytes_reader, huf_table->huf_values, value_count); + huf_table->valid = TRUE; } return GST_JPEG_PARSER_OK; @@ -385,7 +394,7 @@ wrong_state: GstJpegParserResult gst_jpeg_parse_quant_table ( - GstJpegQuantTable *quant_tables, guint num_quant_tables, + GstJpegQuantTables *quant_tables, const guint8 * data, gsize size, guint offset) { GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); @@ -395,13 +404,13 @@ gst_jpeg_parse_quant_table ( guint8 table_index; guint i; - g_assert (quant_tables && num_quant_tables && data && size); + g_assert (quant_tables && data && size); while (gst_byte_reader_get_remaining (&bytes_reader)) { U_READ_UINT8 (&bytes_reader, val); table_index = (val & 0x0f); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS && table_index < num_quant_tables, + CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, GST_JPEG_PARSER_BROKEN_DATA); - quant_table = &quant_tables[table_index]; + quant_table = &quant_tables->quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= GST_JPEG_MAX_QUANT_ELEMENTS * (1 + !!quant_table->quant_precision), @@ -414,6 +423,7 @@ gst_jpeg_parse_quant_table ( U_READ_UINT16 (&bytes_reader, quant_table->quant_table[i]); } } + quant_table->valid = TRUE; } return GST_JPEG_PARSER_OK; @@ -438,23 +448,18 @@ failed: } void -gst_jpeg_get_default_huffman_table (GstJpegHuffmanTables *huf_tables) +gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables) { - g_assert(huf_tables); - memcpy(huf_tables, - &default_huf_tables, - sizeof(GstJpegHuffmanTables)); + g_assert (huf_tables); + + memcpy (huf_tables, &default_huf_tables, sizeof (GstJpegHuffmanTables)); } void -gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, guint num_quant_tables) +gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables) { - int i = 1; - g_assert(quant_tables && num_quant_tables); - for (i = 0; i < num_quant_tables && i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) - memcpy(&quant_tables[i], - &default_quant_tables_zigzag[i], - sizeof(GstJpegQuantTable)); + g_assert (quant_tables); + memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (GstJpegQuantTables)); } static gint32 diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index 38523f2..a3f2b85 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -53,6 +53,7 @@ G_BEGIN_DECLS #define GST_JPEG_MAX_QUANT_ELEMENTS 64 typedef struct _GstJpegQuantTable GstJpegQuantTable; +typedef struct _GstJpegQuantTables GstJpegQuantTables; typedef struct _GstJpegHuffmanTable GstJpegHuffmanTable; typedef struct _GstJpegHuffmanTables GstJpegHuffmanTables; typedef struct _GstJpegScanComponent GstJpegScanComponent; @@ -139,6 +140,8 @@ typedef enum { * GstJpegQuantTable: * @quant_precision: Quantization table element precision (Pq) * @quant_table: Quantization table elements (Qk) + * @valid: If the quantization table is valid, which means it has + * already been parsed * * Quantization table. */ @@ -146,12 +149,27 @@ struct _GstJpegQuantTable { guint8 quant_precision; guint16 quant_table[GST_JPEG_MAX_QUANT_ELEMENTS]; + gboolean valid; +}; + +/** + * GstJpegQuantTables: + * @quant_tables: All quantization tables + * + * Helper data structure that holds all quantization tables used to + * decode an image. + */ +struct _GstJpegQuantTables +{ + GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; }; /** * GstJpegHuffmanTable: * @huf_bits: Number of Huffman codes of length i + 1 (Li) * @huf_vales: Value associated with each Huffman code (Vij) + * @valid: If the Huffman table is valid, which means it has already + * been parsed * * Huffman table. */ @@ -159,6 +177,7 @@ struct _GstJpegHuffmanTable { guint8 huf_bits[16]; guint8 huf_values[256]; + gboolean valid; }; /** @@ -334,17 +353,15 @@ GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, * * Parses the JPEG quantization table structure members from @data. * - * Note: @quant_tables represents the user-allocated quantization - * tables based on the number of scan components. That is, the parser - * writes the output quantization table at the index specified by the - * quantization table destination identifier (Tq). So, the array of - * quantization tables shall be large enough to hold the table for the - * last component. + * Note: @quant_tables represents the complete set of possible + * quantization tables. However, the parser will only write to the + * quantization table specified by the table destination identifier + * (Tq). While doing so, the @valid flag of the specified quantization + * table will also be set to %TRUE. * * Returns: a #GstJpegParserResult */ -GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quant_tables, - guint num_quant_tables, +GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, const guint8 * data, gsize size, guint offset); @@ -360,7 +377,9 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTable *quan * * Note: @huf_tables represents the complete set of possible Huffman * tables. However, the parser will only write to the Huffman table - * specified by the table destination identifier (Th). + * specified by the table destination identifier (Th). While doing so, + * the @valid flag of the specified Huffman table will also be set to + * %TRUE; * * Returns: a #GstJpegParserResult */ @@ -384,24 +403,23 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, guint offset); /** - * gst_jpeg_get_default_huffman_table: - * @huf_tables: (out): The default dc/ac hufman tables to fill in + * gst_jpeg_get_default_huffman_tables: + * @huf_tables: (out): The default DC/AC Huffman tables to fill in * - * Returns: void + * Fills in @huf_tables with the default AC/DC Huffman tables, as + * specified by the JPEG standard. */ -void gst_jpeg_get_default_huffman_table ( +void gst_jpeg_get_default_huffman_tables ( GstJpegHuffmanTables *huf_tables); /** * gst_jpeg_get_default_quantization_table: * @quant_tables: (out): The default luma/chroma quant-tables in zigzag mode - * @num_quant_tables: The number of allocated quantization tables in @quant_tables * * Fills in @quant_tables with the default quantization tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_quantization_table (GstJpegQuantTable *quant_tables, - guint num_quant_tables); +void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index fd03748..a477911 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -52,7 +52,7 @@ struct _GstVaapiDecoderJpegPrivate { GstVaapiPicture *current_picture; GstJpegFrameHdr frame_hdr; GstJpegHuffmanTables huf_tables; - GstJpegQuantTable quant_tables[GST_JPEG_MAX_SCAN_COMPONENTS]; + GstJpegQuantTables quant_tables; gboolean has_huf_table; gboolean has_quant_table; guint mcu_restart; @@ -225,22 +225,24 @@ fill_quantization_table( guint i, j; if (!priv->has_quant_table) - gst_jpeg_get_default_quantization_table(priv->quant_tables, GST_JPEG_MAX_SCAN_COMPONENTS); + gst_jpeg_get_default_quantization_tables(&priv->quant_tables); picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(JPEG, decoder); g_assert(picture->iq_matrix); iq_matrix = picture->iq_matrix->param; memset(iq_matrix, 0, sizeof(VAIQMatrixBufferJPEG)); for (i = 0; i < GST_JPEG_MAX_SCAN_COMPONENTS; i++) { - iq_matrix->precision[i] = priv->quant_tables[i].quant_precision; + GstJpegQuantTable * const quant_table = + &priv->quant_tables.quant_tables[i]; + iq_matrix->precision[i] = quant_table->quant_precision; if (iq_matrix->precision[i] == 0) /* 8-bit values */ for (j = 0; j < GST_JPEG_MAX_QUANT_ELEMENTS; j++) { iq_matrix->quantiser_matrix[i][j] = - priv->quant_tables[i].quant_table[j]; + quant_table->quant_table[j]; } else memcpy(iq_matrix->quantiser_matrix[i], - priv->quant_tables[i].quant_table, + quant_table->quant_table, 128); } return TRUE; @@ -257,7 +259,7 @@ fill_huffman_table( guint i; if (!priv->has_huf_table) - gst_jpeg_get_default_huffman_table(&priv->huf_tables); + gst_jpeg_get_default_huffman_tables(&priv->huf_tables); picture->huf_table = GST_VAAPI_HUFFMAN_TABLE_NEW(JPEG, decoder); g_assert(picture->huf_table); @@ -399,11 +401,7 @@ decode_quant_table( GstVaapiDecoderJpegPrivate * const priv = decoder->priv; GstJpegParserResult result; - result = gst_jpeg_parse_quant_table( - priv->quant_tables, - GST_JPEG_MAX_SCAN_COMPONENTS, - buf, buf_size, 0 - ); + result = gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0); if (result != GST_JPEG_PARSER_OK) { GST_DEBUG("failed to parse quantization table"); return get_status(result); @@ -651,7 +649,7 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder) priv->is_constructed = FALSE; memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr)); memset(&priv->huf_tables, 0, sizeof(priv->huf_tables)); - memset(priv->quant_tables, 0, sizeof(priv->quant_tables)); + memset(&priv->quant_tables, 0, sizeof(priv->quant_tables)); } /**