summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--drivers/amvdec_ports/Makefile13
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c22
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h3
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c534
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h39
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c57
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h11
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c18
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h8
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c9
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.h6
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c662
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_h264_parser.h226
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c1274
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_hevc_parser.h137
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c397
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h163
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.c198
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h74
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c1233
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h250
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c299
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_vp9_parser.h279
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.c389
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.h141
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.c111
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.h39
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c357
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c477
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c498
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c490
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c499
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c461
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/vdec_vp9_trigger.h0
-rw-r--r--drivers/amvdec_ports/test/vcodec_m2m_test.c18
-rw-r--r--drivers/amvdec_ports/utils/common.c221
-rw-r--r--drivers/amvdec_ports/utils/common.h72
-rw-r--r--drivers/amvdec_ports/utils/get_bits.h590
-rw-r--r--drivers/amvdec_ports/utils/golomb.c147
-rw-r--r--drivers/amvdec_ports/utils/golomb.h500
-rw-r--r--drivers/amvdec_ports/utils/pixfmt.h470
-rw-r--r--drivers/amvdec_ports/utils/put_bits.h323
-rw-r--r--drivers/amvdec_ports/vdec_drv_base.h11
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c45
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h10
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c219
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c308
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c334
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c233
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c317
-rw-r--r--drivers/frame_provider/decoder/utils/Makefile1
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c19
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c131
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h22
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c388
55 files changed, 11471 insertions, 2282 deletions
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
new file mode 100644
index 0000000..cf4e0e8
--- a/dev/null
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c
@@ -0,0 +1,662 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include "aml_h264_parser.h"
+#include "../utils/get_bits.h"
+#include "../utils/put_bits.h"
+#include "../utils/golomb.h"
+#include "../utils/common.h"
+#include "utils.h"
+
+#define MAX_DELAYED_PIC_COUNT (16)
+#define MAX_LOG2_MAX_FRAME_NUM (12 + 4)
+#define MIN_LOG2_MAX_FRAME_NUM (4)
+#define MAX_SPS_COUNT (32)
+#define EXTENDED_SAR (255)
+
+static const struct rational h264_pixel_aspect[17] = {
+ { 0, 1 },
+ { 1, 1 },
+ { 12, 11 },
+ { 10, 11 },
+ { 16, 11 },
+ { 40, 33 },
+ { 24, 11 },
+ { 20, 11 },
+ { 32, 11 },
+ { 80, 33 },
+ { 18, 11 },
+ { 15, 11 },
+ { 64, 33 },
+ { 160, 99 },
+ { 4, 3 },
+ { 3, 2 },
+ { 2, 1 },
+};
+
+/* maximum number of MBs in the DPB for a given level */
+static const int level_max_dpb_mbs[][2] = {
+ { 10, 396 },
+ { 11, 900 },
+ { 12, 2376 },
+ { 13, 2376 },
+ { 20, 2376 },
+ { 21, 4752 },
+ { 22, 8100 },
+ { 30, 8100 },
+ { 31, 18000 },
+ { 32, 20480 },
+ { 40, 32768 },
+ { 41, 32768 },
+ { 42, 34816 },
+ { 50, 110400 },
+ { 51, 184320 },
+ { 52, 184320 },
+};
+
+static const u8 default_scaling4[2][16] = {
+ { 6, 13, 20, 28, 13, 20, 28, 32,
+ 20, 28, 32, 37, 28, 32, 37, 42},
+ { 10, 14, 20, 24, 14, 20, 24, 27,
+ 20, 24, 27, 30, 24, 27, 30, 34 }
+};
+
+static const u8 default_scaling8[2][64] = {
+ { 6, 10, 13, 16, 18, 23, 25, 27,
+ 10, 11, 16, 18, 23, 25, 27, 29,
+ 13, 16, 18, 23, 25, 27, 29, 31,
+ 16, 18, 23, 25, 27, 29, 31, 33,
+ 18, 23, 25, 27, 29, 31, 33, 36,
+ 23, 25, 27, 29, 31, 33, 36, 38,
+ 25, 27, 29, 31, 33, 36, 38, 40,
+ 27, 29, 31, 33, 36, 38, 40, 42 },
+ { 9, 13, 15, 17, 19, 21, 22, 24,
+ 13, 13, 17, 19, 21, 22, 24, 25,
+ 15, 17, 19, 21, 22, 24, 25, 27,
+ 17, 19, 21, 22, 24, 25, 27, 28,
+ 19, 21, 22, 24, 25, 27, 28, 30,
+ 21, 22, 24, 25, 27, 28, 30, 32,
+ 22, 24, 25, 27, 28, 30, 32, 33,
+ 24, 25, 27, 28, 30, 32, 33, 35 }
+};
+
+extern const u8 ff_zigzag_scan[16 + 1];
+extern const u8 ff_zigzag_direct[64];
+
+static int decode_scaling_list(struct get_bits_context *gb,
+ u8 *factors, int size,
+ const u8 *jvt_list,
+ const u8 *fallback_list)
+{
+ int i, last = 8, next = 8;
+ const u8 *scan = size == 16 ? ff_zigzag_scan : ff_zigzag_direct;
+
+ if (!get_bits1(gb)) /* matrix not written, we use the predicted one */
+ memcpy(factors, fallback_list, size * sizeof(u8));
+ else
+ for (i = 0; i < size; i++) {
+ if (next) {
+ int v = get_se_golomb(gb);
+ if (v < -128 || v > 127) {
+ pr_err( "delta scale %d is invalid\n", v);
+ return -1;
+ }
+ next = (last + v) & 0xff;
+ }
+ if (!i && !next) { /* matrix not written, we use the preset one */
+ memcpy(factors, jvt_list, size * sizeof(u8));
+ break;
+ }
+ last = factors[scan[i]] = next ? next : last;
+ }
+ return 0;
+}
+
+/* returns non zero if the provided SPS scaling matrix has been filled */
+static int decode_scaling_matrices(struct get_bits_context *gb,
+ const struct h264_SPS_t *sps,
+ const struct h264_PPS_t *pps, int is_sps,
+ u8(*scaling_matrix4)[16],
+ u8(*scaling_matrix8)[64])
+{
+ int ret = 0;
+ int fallback_sps = !is_sps && sps->scaling_matrix_present;
+ const u8 *fallback[4] = {
+ fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
+ fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1],
+ fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
+ fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
+ };
+
+ if (get_bits1(gb)) {
+ ret |= decode_scaling_list(gb, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y
+ ret |= decode_scaling_list(gb, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
+ ret |= decode_scaling_list(gb, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
+ ret |= decode_scaling_list(gb, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y
+ ret |= decode_scaling_list(gb, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
+ ret |= decode_scaling_list(gb, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
+ if (is_sps || pps->transform_8x8_mode) {
+ ret |= decode_scaling_list(gb, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y
+ ret |= decode_scaling_list(gb, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y
+ if (sps->chroma_format_idc == 3) {
+ ret |= decode_scaling_list(gb, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr
+ ret |= decode_scaling_list(gb, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
+ ret |= decode_scaling_list(gb, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb
+ ret |= decode_scaling_list(gb, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
+ }
+ }
+ if (!ret)
+ ret = is_sps;
+ }
+
+ return ret;
+}
+
+static int decode_hrd_parameters(struct get_bits_context *gb,
+ struct h264_SPS_t *sps)
+{
+ int cpb_count, i;
+
+ cpb_count = get_ue_golomb_31(gb) + 1;
+ if (cpb_count > 32U) {
+ pr_err("cpb_count %d invalid\n", cpb_count);
+ return -1;
+ }
+
+ get_bits(gb, 4); /* bit_rate_scale */
+ get_bits(gb, 4); /* cpb_size_scale */
+ for (i = 0; i < cpb_count; i++) {
+ get_ue_golomb_long(gb); /* bit_rate_value_minus1 */
+ get_ue_golomb_long(gb); /* cpb_size_value_minus1 */
+ get_bits1(gb); /* cbr_flag */
+ }
+
+ sps->initial_cpb_removal_delay_length = get_bits(gb, 5) + 1;
+ sps->cpb_removal_delay_length = get_bits(gb, 5) + 1;
+ sps->dpb_output_delay_length = get_bits(gb, 5) + 1;
+ sps->time_offset_length = get_bits(gb, 5);
+ sps->cpb_cnt = cpb_count;
+
+ return 0;
+}
+
+static int decode_vui_parameters(struct get_bits_context *gb, struct h264_SPS_t *sps)
+{
+ int aspect_ratio_info_present_flag;
+ u32 aspect_ratio_idc;
+
+ aspect_ratio_info_present_flag = get_bits1(gb);
+
+ if (aspect_ratio_info_present_flag) {
+ aspect_ratio_idc = get_bits(gb, 8);
+ if (aspect_ratio_idc == EXTENDED_SAR) {
+ sps->sar.num = get_bits(gb, 16);
+ sps->sar.den = get_bits(gb, 16);
+ } else if (aspect_ratio_idc < ARRAY_SIZE(h264_pixel_aspect)) {
+ sps->sar = h264_pixel_aspect[aspect_ratio_idc];
+ } else {
+ return -1;
+ }
+ } else {
+ sps->sar.num =
+ sps->sar.den = 0;
+ }
+
+ if (get_bits1(gb)) /* overscan_info_present_flag */
+ get_bits1(gb); /* overscan_appropriate_flag */
+
+ sps->video_signal_type_present_flag = get_bits1(gb);
+ if (sps->video_signal_type_present_flag) {
+ get_bits(gb, 3); /* video_format */
+ sps->full_range = get_bits1(gb); /* video_full_range_flag */
+
+ sps->colour_description_present_flag = get_bits1(gb);
+ if (sps->colour_description_present_flag) {
+ sps->color_primaries = get_bits(gb, 8); /* colour_primaries */
+ sps->color_trc = get_bits(gb, 8); /* transfer_characteristics */
+ sps->colorspace = get_bits(gb, 8); /* matrix_coefficients */
+
+ // Set invalid values to "unspecified"
+ if (!av_color_primaries_name(sps->color_primaries))
+ sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
+ if (!av_color_transfer_name(sps->color_trc))
+ sps->color_trc = AVCOL_TRC_UNSPECIFIED;
+ if (!av_color_space_name(sps->colorspace))
+ sps->colorspace = AVCOL_SPC_UNSPECIFIED;
+ }
+ }
+
+ /* chroma_location_info_present_flag */
+ if (get_bits1(gb)) {
+ /* chroma_sample_location_type_top_field */
+ //avctx->chroma_sample_location = get_ue_golomb(gb) + 1;
+ get_ue_golomb(gb); /* chroma_sample_location_type_bottom_field */
+ }
+
+ if (show_bits1(gb) && get_bits_left(gb) < 10) {
+ pr_info("Truncated VUI\n");
+ return 0;
+ }
+
+ sps->timing_info_present_flag = get_bits1(gb);
+ if (sps->timing_info_present_flag) {
+ unsigned num_units_in_tick = get_bits_long(gb, 32);
+ unsigned time_scale = get_bits_long(gb, 32);
+ if (!num_units_in_tick || !time_scale) {
+ pr_info("time_scale/num_units_in_tick invalid or unsupported (%u/%u)\n",
+ time_scale, num_units_in_tick);
+ sps->timing_info_present_flag = 0;
+ } else {
+ sps->num_units_in_tick = num_units_in_tick;
+ sps->time_scale = time_scale;
+ }
+ sps->fixed_frame_rate_flag = get_bits1(gb);
+ }
+
+ sps->nal_hrd_parameters_present_flag = get_bits1(gb);
+ if (sps->nal_hrd_parameters_present_flag)
+ if (decode_hrd_parameters(gb, sps) < 0)
+ return -1;
+ sps->vcl_hrd_parameters_present_flag = get_bits1(gb);
+ if (sps->vcl_hrd_parameters_present_flag)
+ if (decode_hrd_parameters(gb, sps) < 0)
+ return -1;
+ if (sps->nal_hrd_parameters_present_flag ||
+ sps->vcl_hrd_parameters_present_flag)
+ get_bits1(gb); /* low_delay_hrd_flag */
+ sps->pic_struct_present_flag = get_bits1(gb);
+ if (!get_bits_left(gb))
+ return 0;
+ sps->bitstream_restriction_flag = get_bits1(gb);
+ if (sps->bitstream_restriction_flag) {
+ get_bits1(gb); /* motion_vectors_over_pic_boundaries_flag */
+ get_ue_golomb(gb); /* max_bytes_per_pic_denom */
+ get_ue_golomb(gb); /* max_bits_per_mb_denom */
+ get_ue_golomb(gb); /* log2_max_mv_length_horizontal */
+ get_ue_golomb(gb); /* log2_max_mv_length_vertical */
+ sps->num_reorder_frames = get_ue_golomb(gb);
+ sps->max_dec_frame_buffering = get_ue_golomb(gb); /*max_dec_frame_buffering*/
+
+ if (get_bits_left(gb) < 0) {
+ sps->num_reorder_frames = 0;
+ sps->bitstream_restriction_flag = 0;
+ }
+
+ if (sps->num_reorder_frames > 16U
+ /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
+ pr_info("Clipping illegal num_reorder_frames %d\n",
+ sps->num_reorder_frames);
+ sps->num_reorder_frames = 16;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *sps)
+{
+ int ret;
+ u32 sps_id;
+ int profile_idc, level_idc, constraint_set_flags = 0;
+ int i, log2_max_frame_num_minus4;
+
+ profile_idc = get_bits(gb, 8);
+ constraint_set_flags |= get_bits1(gb) << 0; // constraint_set0_flag
+ constraint_set_flags |= get_bits1(gb) << 1; // constraint_set1_flag
+ constraint_set_flags |= get_bits1(gb) << 2; // constraint_set2_flag
+ constraint_set_flags |= get_bits1(gb) << 3; // constraint_set3_flag
+ constraint_set_flags |= get_bits1(gb) << 4; // constraint_set4_flag
+ constraint_set_flags |= get_bits1(gb) << 5; // constraint_set5_flag
+ skip_bits(gb, 2); // reserved_zero_2bits
+ level_idc = get_bits(gb, 8);
+ sps_id = get_ue_golomb_31(gb);
+
+ if (sps_id >= MAX_SPS_COUNT) {
+ pr_info( "sps_id %u out of range\n", sps_id);
+ goto fail;
+ }
+
+ sps->sps_id = sps_id;
+ sps->time_offset_length = 24;
+ sps->profile_idc = profile_idc;
+ sps->constraint_set_flags = constraint_set_flags;
+ sps->level_idc = level_idc;
+ sps->full_range = -1;
+
+ memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
+ memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
+ sps->scaling_matrix_present = 0;
+ sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
+
+ if (sps->profile_idc == 100 || // High profile
+ sps->profile_idc == 110 || // High10 profile
+ sps->profile_idc == 122 || // High422 profile
+ sps->profile_idc == 244 || // High444 Predictive profile
+ sps->profile_idc == 44 || // Cavlc444 profile
+ sps->profile_idc == 83 || // Scalable Constrained High profile (SVC)
+ sps->profile_idc == 86 || // Scalable High Intra profile (SVC)
+ sps->profile_idc == 118 || // Stereo High profile (MVC)
+ sps->profile_idc == 128 || // Multiview High profile (MVC)
+ sps->profile_idc == 138 || // Multiview Depth High profile (MVCD)
+ sps->profile_idc == 144) { // old High444 profile
+ sps->chroma_format_idc = get_ue_golomb_31(gb);
+
+ if (sps->chroma_format_idc > 3U) {
+ pr_err("chroma_format_idc %u\n", sps->chroma_format_idc);
+ goto fail;
+ } else if (sps->chroma_format_idc == 3) {
+ sps->residual_color_transform_flag = get_bits1(gb);
+ if (sps->residual_color_transform_flag) {
+ pr_info( "separate color planes are not supported\n");
+ goto fail;
+ }
+ }
+
+ sps->bit_depth_luma = get_ue_golomb(gb) + 8;
+ sps->bit_depth_chroma = get_ue_golomb(gb) + 8;
+ if (sps->bit_depth_chroma != sps->bit_depth_luma) {
+ pr_err("Different chroma and luma bit depth\n");
+ goto fail;
+ }
+
+ if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 ||
+ sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14) {
+ pr_info("illegal bit depth value (%d, %d)\n",
+ sps->bit_depth_luma, sps->bit_depth_chroma);
+ goto fail;
+ }
+
+ sps->transform_bypass = get_bits1(gb);
+ ret = decode_scaling_matrices(gb, sps, NULL, 1,
+ sps->scaling_matrix4, sps->scaling_matrix8);
+ if (ret < 0)
+ goto fail;
+ sps->scaling_matrix_present |= ret;
+ } else {
+ sps->chroma_format_idc = 1;
+ sps->bit_depth_luma = 8;
+ sps->bit_depth_chroma = 8;
+ }
+
+ log2_max_frame_num_minus4 = get_ue_golomb(gb);
+ if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
+ log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) {
+ pr_info(
+ "log2_max_frame_num_minus4 out of range (0-12): %d\n",
+ log2_max_frame_num_minus4);
+ goto fail;
+ }
+ sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
+
+ sps->poc_type = get_ue_golomb_31(gb);
+ if (sps->poc_type == 0) { // FIXME #define
+ u32 t = get_ue_golomb(gb);
+ if (t > 12) {
+ pr_info( "log2_max_poc_lsb (%d) is out of range\n", t);
+ goto fail;
+ }
+ sps->log2_max_poc_lsb = t + 4;
+ } else if (sps->poc_type == 1) { // FIXME #define
+ sps->delta_pic_order_always_zero_flag = get_bits1(gb);
+ sps->offset_for_non_ref_pic = get_se_golomb_long(gb);
+ sps->offset_for_top_to_bottom_field = get_se_golomb_long(gb);
+
+ sps->poc_cycle_length = get_ue_golomb(gb);
+ if ((u32)sps->poc_cycle_length >= ARRAY_SIZE(sps->offset_for_ref_frame)) {
+ pr_info("poc_cycle_length overflow %d\n", sps->poc_cycle_length);
+ goto fail;
+ }
+
+ for (i = 0; i < sps->poc_cycle_length; i++)
+ sps->offset_for_ref_frame[i] = get_se_golomb_long(gb);
+ } else if (sps->poc_type != 2) {
+ pr_info( "illegal POC type %d\n", sps->poc_type);
+ goto fail;
+ }
+
+ sps->ref_frame_count = get_ue_golomb_31(gb);
+ if (sps->ref_frame_count > MAX_DELAYED_PIC_COUNT) {
+ pr_info("too many reference frames %d\n", sps->ref_frame_count);
+ goto fail;
+ }
+ sps->gaps_in_frame_num_allowed_flag = get_bits1(gb);
+ sps->mb_width = get_ue_golomb(gb) + 1;
+ sps->mb_height = get_ue_golomb(gb) + 1;
+
+ sps->frame_mbs_only_flag = get_bits1(gb);
+
+ if (sps->mb_height >= INT_MAX / 2U) {
+ pr_info("height overflow\n");
+ goto fail;
+ }
+ sps->mb_height *= 2 - sps->frame_mbs_only_flag;
+
+ if (!sps->frame_mbs_only_flag)
+ sps->mb_aff = get_bits1(gb);
+ else
+ sps->mb_aff = 0;
+
+ if ((u32)sps->mb_width >= INT_MAX / 16 ||
+ (u32)sps->mb_height >= INT_MAX / 16) {
+ pr_info( "mb_width/height overflow\n");
+ goto fail;
+ }
+
+ sps->direct_8x8_inference_flag = get_bits1(gb);
+
+ sps->crop = get_bits1(gb);
+ if (sps->crop) {
+ u32 crop_left = get_ue_golomb(gb);
+ u32 crop_right = get_ue_golomb(gb);
+ u32 crop_top = get_ue_golomb(gb);
+ u32 crop_bottom = get_ue_golomb(gb);
+ int width = 16 * sps->mb_width;
+ int height = 16 * sps->mb_height;
+ int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
+ int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0;
+ int step_x = 1 << hsub;
+ int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
+
+ if (crop_left > (u32)INT_MAX / 4 / step_x ||
+ crop_right > (u32)INT_MAX / 4 / step_x ||
+ crop_top > (u32)INT_MAX / 4 / step_y ||
+ crop_bottom > (u32)INT_MAX / 4 / step_y ||
+ (crop_left + crop_right ) * step_x >= width ||
+ (crop_top + crop_bottom) * step_y >= height) {
+ pr_info( "crop values invalid %u %u %u %u / %d %d\n", crop_left, crop_right, crop_top, crop_bottom, width, height);
+ goto fail;
+ }
+
+ sps->crop_left = crop_left * step_x;
+ sps->crop_right = crop_right * step_x;
+ sps->crop_top = crop_top * step_y;
+ sps->crop_bottom = crop_bottom * step_y;
+ } else {
+ sps->crop_left =
+ sps->crop_right =
+ sps->crop_top =
+ sps->crop_bottom =
+ sps->crop = 0;
+ }
+
+ sps->vui_parameters_present_flag = get_bits1(gb);
+ if (sps->vui_parameters_present_flag) {
+ int ret = decode_vui_parameters(gb, sps);
+ if (ret < 0)
+ goto fail;
+ }
+
+ if (get_bits_left(gb) < 0) {
+ pr_info("Overread %s by %d bits\n", sps->vui_parameters_present_flag ? "VUI" : "SPS", -get_bits_left(gb));
+ goto out;
+ }
+
+ /* if the maximum delay is not stored in the SPS, derive it based on the level */
+ if (!sps->bitstream_restriction_flag && sps->ref_frame_count) {
+ sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
+ for (i = 0; i < ARRAY_SIZE(level_max_dpb_mbs); i++) {
+ if (level_max_dpb_mbs[i][0] == sps->level_idc) {
+ sps->num_reorder_frames =
+ MIN(level_max_dpb_mbs[i][1] / (sps->mb_width * sps->mb_height),
+ sps->num_reorder_frames);
+ break;
+ }
+ }
+ }
+
+ if (!sps->sar.den)
+ sps->sar.den = 1;
+out:
+ if (1) {
+ static const char csp[4][5] = { "Gray", "420", "422", "444" };
+ pr_info("sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%u/%u/%u/%u %s %s %d/%d b%d reo:%d\n",
+ sps_id, sps->profile_idc, sps->level_idc,
+ sps->poc_type,
+ sps->ref_frame_count,
+ sps->mb_width, sps->mb_height,
+ sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"),
+ sps->direct_8x8_inference_flag ? "8B8" : "",
+ sps->crop_left, sps->crop_right,
+ sps->crop_top, sps->crop_bottom,
+ sps->vui_parameters_present_flag ? "VUI" : "",
+ csp[sps->chroma_format_idc],
+ sps->timing_info_present_flag ? sps->num_units_in_tick : 0,
+ sps->timing_info_present_flag ? sps->time_scale : 0,
+ sps->bit_depth_luma,
+ sps->bitstream_restriction_flag ? sps->num_reorder_frames : -1);
+ }
+
+ return 0;
+
+fail:
+ return -1;
+}
+
+static const char *h264_nal_type_name[32] = {
+ "Unspecified 0", //H264_NAL_UNSPECIFIED
+ "Coded slice of a non-IDR picture", // H264_NAL_SLICE
+ "Coded slice data partition A", // H264_NAL_DPA
+ "Coded slice data partition B", // H264_NAL_DPB
+ "Coded slice data partition C", // H264_NAL_DPC
+ "IDR", // H264_NAL_IDR_SLICE
+ "SEI", // H264_NAL_SEI
+ "SPS", // H264_NAL_SPS
+ "PPS", // H264_NAL_PPS
+ "AUD", // H264_NAL_AUD
+ "End of sequence", // H264_NAL_END_SEQUENCE
+ "End of stream", // H264_NAL_END_STREAM
+ "Filler data", // H264_NAL_FILLER_DATA
+ "SPS extension", // H264_NAL_SPS_EXT
+ "Prefix", // H264_NAL_PREFIX
+ "Subset SPS", // H264_NAL_SUB_SPS
+ "Depth parameter set", // H264_NAL_DPS
+ "Reserved 17", // H264_NAL_RESERVED17
+ "Reserved 18", // H264_NAL_RESERVED18
+ "Auxiliary coded picture without partitioning", // H264_NAL_AUXILIARY_SLICE
+ "Slice extension", // H264_NAL_EXTEN_SLICE
+ "Slice extension for a depth view or a 3D-AVC texture view", // H264_NAL_DEPTH_EXTEN_SLICE
+ "Reserved 22", // H264_NAL_RESERVED22
+ "Reserved 23", // H264_NAL_RESERVED23
+ "Unspecified 24", // H264_NAL_UNSPECIFIED24
+ "Unspecified 25", // H264_NAL_UNSPECIFIED25
+ "Unspecified 26", // H264_NAL_UNSPECIFIED26
+ "Unspecified 27", // H264_NAL_UNSPECIFIED27
+ "Unspecified 28", // H264_NAL_UNSPECIFIED28
+ "Unspecified 29", // H264_NAL_UNSPECIFIED29
+ "Unspecified 30", // H264_NAL_UNSPECIFIED30
+ "Unspecified 31", // H264_NAL_UNSPECIFIED31
+};
+
+static const char *h264_nal_unit_name(int nal_type)
+{
+ return h264_nal_type_name[nal_type];
+}
+
+static int decode_extradata_ps(u8 *data, int size, struct h264_param_sets *ps)
+{
+ int ret = 0;
+ struct get_bits_context gb;
+ u32 src_len, rbsp_size = 0;
+ u8 *rbsp_buf = NULL;
+ int ref_idc, nalu_pos;
+ u32 nal_type;
+ u8 *p = data;
+ u32 len = size;
+
+ nalu_pos = find_start_code(p, len);
+ if (nalu_pos < 0)
+ return -1;
+
+ src_len = calc_nal_len(p + nalu_pos, size - nalu_pos);
+ rbsp_buf = nal_unit_extract_rbsp(p + nalu_pos, src_len, &rbsp_size);
+ if (rbsp_buf == NULL)
+ return -ENOMEM;
+
+ ret = init_get_bits8(&gb, rbsp_buf, rbsp_size);
+ if (ret < 0)
+ goto out;
+
+ if (get_bits1(&gb) != 0) {
+ pr_err("invalid h264 data,return!\n");
+ goto out;
+ }
+
+ ref_idc = get_bits(&gb, 2);
+ nal_type = get_bits(&gb, 5);
+
+ pr_info("nal_unit_type: %d(%s), nal_ref_idc: %d\n",
+ nal_type, h264_nal_unit_name(nal_type), ref_idc);
+
+ switch (nal_type) {
+ case H264_NAL_SPS:
+ ret = aml_h264_parser_sps(&gb, &ps->sps);
+ if (ret < 0)
+ goto out;
+ ps->sps_parsed = true;
+ break;
+ /*case H264_NAL_PPS:
+ ret = ff_h264_decode_picture_parameter_set(&gb, &ps->pps, rbsp_size);
+ if (ret < 0)
+ goto fail;
+ ps->pps_parsed = true;
+ break;*/
+ default:
+ pr_err("Unsupport parser nal type (%s).\n",
+ h264_nal_unit_name(nal_type));
+ break;
+ }
+
+out:
+ vfree(rbsp_buf);
+
+ return ret;
+}
+
+int h264_decode_extradata_ps(u8 *buf, int size, struct h264_param_sets *ps)
+{
+ int ret = 0, i = 0, j = 0;
+ u8 *p = buf;
+ int len = size;
+
+ for (i = 4; i < size; i++) {
+ j = find_start_code(p, len);
+ if (j > 0) {
+ len = size - (p - buf);
+ ret = decode_extradata_ps(p, len, ps);
+ if (ret) {
+ pr_err("parse extra data failed. err: %d\n", ret);
+ return ret;
+ }
+ p += j;
+ }
+ p++;
+ }
+
+ return ret;
+}
+
+