blob: 12447a47e590dd74bf796c42a4f473d9f2ce169c [file] [log] [blame]
#ifndef VIDDEC_MP4_PARSE_H
#define VIDDEC_MP4_PARSE_H
#include "viddec_fw_debug.h"
#include "viddec_fw_mp4.h"
/* Macros for MP4 start code detection */
#define FIRST_STARTCODE_BYTE 0x00
#define SECOND_STARTCODE_BYTE 0x00
#define THIRD_STARTCODE_BYTE 0x01
#define SHORT_THIRD_STARTCODE_BYTE 0x80
#define SC_BYTE_MASK0 0x00ff0000
#define SC_BYTE_MASK1 0x000000ff
/* status codes */
typedef enum
{
MP4_STATUS_OK = 0, /* Success */
MP4_STATUS_PARSE_ERROR = (1 << 0), /* Invalid syntax */
MP4_STATUS_NOTSUPPORT = (1 << 1), /* unsupported feature */
MP4_STATUS_REQD_DATA_ERROR = (1 << 2), /* supported data either invalid or missing */
} mp4_Status_t;
/* feature codes */
typedef enum
{
MP4_VOP_FEATURE_DEFAULT = 0, // Default VOP features, no code image update needed
MP4_VOP_FEATURE_SVH = 1, // VOP has Short Video Header
MP4_VOP_FEATURE_DP = 2 // VOP is Data Partitioned
} mp4_Vop_feature;
/* MPEG-4 start code values: Table 6-3 */
typedef enum
{
MP4_SC_VIDEO_OBJECT_MIN = 0x00,
MP4_SC_VIDEO_OBJECT_MAX = 0x1F,
MP4_SC_VIDEO_OBJECT_LAYER_MIN = 0x20,
MP4_SC_VIDEO_OBJECT_LAYER_MAX = 0x2F,
MP4_SC_FGS_BP_MIN = 0x40, /* Unsupported */
MP4_SC_FGS_BP_MAX = 0x5F, /* Unsupported */
MP4_SC_VISUAL_OBJECT_SEQUENCE = 0xB0,
MP4_SC_VISUAL_OBJECT_SEQUENCE_EC = 0xB1,
MP4_SC_USER_DATA = 0xB2,
MP4_SC_GROUP_OF_VOP = 0xB3,
MP4_SC_VIDEO_SESSION_ERROR = 0xB4,
MP4_SC_VISUAL_OBJECT = 0xB5,
MP4_SC_VIDEO_OBJECT_PLANE = 0xB6,
MP4_SC_SLICE = 0xB7, /* Unsupported */
MP4_SC_EXTENSION = 0xB8, /* Unsupported */
MP4_SC_FGS_VOP = 0xB9, /* Unsupported */
MP4_SC_FBA_OBJECT = 0xBA, /* Unsupported */
MP4_SC_FBA_OBJECT_PLANE = 0xBB, /* Unsupported */
MP4_SC_MESH_OBJECT = 0xBC, /* Unsupported */
MP4_SC_MESH_OBJECT_PLANE = 0xBD, /* Unsupported */
MP4_SC_STILL_TEXTURE_OBJECT = 0xBE, /* Unsupported */
MP4_SC_TEXTURE_SPATIAL_LAYER = 0xBF, /* Unsupported */
MP4_SC_TEXTURE_SNR_LAYER = 0xC0, /* Unsupported */
MP4_SC_TEXTURE_TILE = 0xC1, /* Unsupported */
MP4_SC_TEXTURE_SHAPE_LAYER = 0xC2, /* Unsupported */
MP4_SC_STUFFING = 0xC3,
MP4_SC_SYTEM_MIN = 0xC6, /* Unsupported */
MP4_SC_SYTEM_MAX = 0xFF, /* Unsupported */
MP4_SC_INVALID = 0x100, /* Invalid */
}mp4_start_code_values_t;
/* MPEG-4 code values
ISO/IEC 14496-2:2004 table 6-6 */
enum
{
MP4_VISUAL_OBJECT_TYPE_VIDEO = 1,
MP4_VISUAL_OBJECT_TYPE_TEXTURE = 2,
MP4_VISUAL_OBJECT_TYPE_MESH = 3,
MP4_VISUAL_OBJECT_TYPE_FBA = 4,
MP4_VISUAL_OBJECT_TYPE_3DMESH = 5
};
/* ISO/IEC 14496-2:2004 table 6-7 */
enum
{
MP4_VIDEO_FORMAT_COMPONENT = 0,
MP4_VIDEO_FORMAT_PAL = 1,
MP4_VIDEO_FORMAT_NTSC = 2,
MP4_VIDEO_FORMAT_SECAM = 3,
MP4_VIDEO_FORMAT_MAC = 4,
MP4_VIDEO_FORMAT_UNSPECIFIED = 5
};
/* ISO/IEC 14496-2:2004 table 6-8..10 */
enum
{
MP4_VIDEO_COLORS_FORBIDDEN = 0,
MP4_VIDEO_COLORS_ITU_R_BT_709 = 1,
MP4_VIDEO_COLORS_UNSPECIFIED = 2,
MP4_VIDEO_COLORS_RESERVED = 3,
MP4_VIDEO_COLORS_ITU_R_BT_470_2_M = 4,
MP4_VIDEO_COLORS_ITU_R_BT_470_2_BG = 5,
MP4_VIDEO_COLORS_SMPTE_170M = 6,
MP4_VIDEO_COLORS_SMPTE_240M = 7,
MP4_VIDEO_COLORS_GENERIC_FILM = 8
};
/* ISO/IEC 14496-2:2004 table 6-11 */
enum
{
MP4_VIDEO_OBJECT_TYPE_SIMPLE = 1,
MP4_VIDEO_OBJECT_TYPE_SIMPLE_SCALABLE = 2,
MP4_VIDEO_OBJECT_TYPE_CORE = 3,
MP4_VIDEO_OBJECT_TYPE_MAIN = 4,
MP4_VIDEO_OBJECT_TYPE_NBIT = 5,
MP4_VIDEO_OBJECT_TYPE_2DTEXTURE = 6,
MP4_VIDEO_OBJECT_TYPE_2DMESH = 7,
MP4_VIDEO_OBJECT_TYPE_SIMPLE_FACE = 8,
MP4_VIDEO_OBJECT_TYPE_STILL_SCALABLE_TEXTURE = 9,
MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE = 10,
MP4_VIDEO_OBJECT_TYPE_CORE_SCALABLE = 11,
MP4_VIDEO_OBJECT_TYPE_ADVANCED_CODING_EFFICIENCY = 12,
MP4_VIDEO_OBJECT_TYPE_ADVANCED_SCALABLE_TEXTURE = 13,
MP4_VIDEO_OBJECT_TYPE_SIMPLE_FBA = 14,
MP4_VIDEO_OBJECT_TYPE_SIMPLE_STUDIO = 15,
MP4_VIDEO_OBJECT_TYPE_CORE_STUDIO = 16,
MP4_VIDEO_OBJECT_TYPE_ADVANCED_SIMPLE = 17,
MP4_VIDEO_OBJECT_TYPE_FINE_GRANULARITY_SCALABLE = 18
};
/* ISO/IEC 14496-2:2004 table 6.17 (maximum defined video_object_layer_shape_extension) */
#define MP4_SHAPE_EXT_NUM 13
/* ISO/IEC 14496-2:2004 table 6-14 */
enum
{
MP4_ASPECT_RATIO_FORBIDDEN = 0,
MP4_ASPECT_RATIO_1_1 = 1,
MP4_ASPECT_RATIO_12_11 = 2,
MP4_ASPECT_RATIO_10_11 = 3,
MP4_ASPECT_RATIO_16_11 = 4,
MP4_ASPECT_RATIO_40_33 = 5,
MP4_ASPECT_RATIO_EXTPAR = 15
};
/* ISO/IEC 14496-2:2004 table 6-15 */
#define MP4_CHROMA_FORMAT_420 1
/* ISO/IEC 14496-2:2004 table 6-16 */
enum
{
MP4_SHAPE_TYPE_RECTANGULAR = 0,
MP4_SHAPE_TYPE_BINARY = 1,
MP4_SHAPE_TYPE_BINARYONLY = 2,
MP4_SHAPE_TYPE_GRAYSCALE = 3
};
/* ISO/IEC 14496-2:2004 table 6-19 */
#define MP4_SPRITE_STATIC 1
#define MP4_SPRITE_GMC 2
/* ISO/IEC 14496-2:2004 table 6-24 */
enum
{
MP4_VOP_TYPE_I = 0,
MP4_VOP_TYPE_P = 1,
MP4_VOP_TYPE_B = 2,
MP4_VOP_TYPE_S = 3,
};
/* ISO/IEC 14496-2:2004 table 6-26 */
enum
{
MP4_SPRITE_TRANSMIT_MODE_STOP = 0,
MP4_SPRITE_TRANSMIT_MODE_PIECE = 1,
MP4_SPRITE_TRANSMIT_MODE_UPDATE = 2,
MP4_SPRITE_TRANSMIT_MODE_PAUSE = 3
};
/* ISO/IEC 14496-2:2004 table 7-3 */
enum
{
MP4_BAB_TYPE_MVDSZ_NOUPDATE = 0,
MP4_BAB_TYPE_MVDSNZ_NOUPDATE = 1,
MP4_BAB_TYPE_TRANSPARENT = 2,
MP4_BAB_TYPE_OPAQUE = 3,
MP4_BAB_TYPE_INTRACAE = 4,
MP4_BAB_TYPE_MVDSZ_INTERCAE = 5,
MP4_BAB_TYPE_MVDSNZ_INTERCAE = 6
};
#define MP4_DC_MARKER 0x6B001 // 110 1011 0000 0000 0001
#define MP4_MV_MARKER 0x1F001 // 1 1111 0000 0000 0001
/* ISO/IEC 14496-2:2004 table G.1 */
enum
{
MP4_SIMPLE_PROFILE_LEVEL_1 = 0x01,
MP4_SIMPLE_PROFILE_LEVEL_2 = 0x02,
MP4_SIMPLE_PROFILE_LEVEL_3 = 0x03,
MP4_SIMPLE_PROFILE_LEVEL_4a = 0x04,
MP4_SIMPLE_PROFILE_LEVEL_5 = 0x05,
MP4_SIMPLE_PROFILE_LEVEL_6 = 0x06,
MP4_SIMPLE_PROFILE_LEVEL_0 = 0x08,
MP4_CORE_PROFILE_LEVEL_1 = 0x21,
MP4_CORE_PROFILE_LEVEL_2 = 0x22,
MP4_MAIN_PROFILE_LEVEL_2 = 0x32,
MP4_MAIN_PROFILE_LEVEL_3 = 0x33,
MP4_MAIN_PROFILE_LEVEL_4 = 0x34,
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_1 = 0x91,
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_2 = 0x92,
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_3 = 0x93,
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_4 = 0x94,
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_1 = 0xB1,
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_2 = 0xB2,
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_3 = 0xB3,
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_4 = 0xB4,
MP4_ADVANCED_CORE_PROFILE_LEVEL_1 = 0xC1,
MP4_ADVANCED_CORE_PROFILE_LEVEL_2 = 0xC2,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_0 = 0xF0,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_1 = 0xF1,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_2 = 0xF2,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3 = 0xF3,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_4 = 0xF4,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_5 = 0xF5,
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3B = 0xF7
};
/* Group Of Video Object Plane Info */
typedef struct
{
uint8_t closed_gov;
uint8_t broken_link;
uint8_t time_code_hours;
uint8_t time_code_minutes;
uint8_t time_code_seconds;
uint8_t dummy1;
uint16_t dummy2;
uint32_t time_base;
} mp4_GroupOfVideoObjectPlane_t;
/* Video Object Plane Info */
typedef struct
{
uint8_t vop_coding_type;
uint32_t modulo_time_base;
uint16_t vop_time_increment;
uint8_t vop_coded;
uint16_t vop_id;
uint16_t vop_id_for_prediction;
uint8_t is_vop_id_for_prediction_indication;
uint8_t vop_rounding_type;
uint8_t vop_reduced_resolution;
uint8_t align_dummy;
uint16_t vop_width;
uint16_t vop_height;
uint16_t vop_horizontal_mc_spatial_ref;
uint16_t vop_vertical_mc_spatial_ref;
uint8_t background_composition;
uint8_t change_conv_ratio_disable;
uint8_t is_vop_constant_alpha;
uint8_t vop_constant_alpha_value;
uint8_t intra_dc_vlc_thr;
uint8_t top_field_first;
uint8_t alternate_vertical_scan_flag;
uint8_t sprite_transmit_mode;
int32_t brightness_change_factor;
uint16_t vop_quant;
uint8_t vop_fcode_forward;
uint8_t vop_fcode_backward;
uint16_t warping_mv_code_du[4];
uint16_t warping_mv_code_dv[4];
} mp4_VideoObjectPlane_t;
/* VOLControlParameters Info */
typedef struct
{
uint8_t chroma_format;
uint8_t low_delay;
uint8_t vbv_parameters;
uint8_t align_dummy1;
uint32_t bit_rate;
uint32_t vbv_buffer_size;
uint32_t vbv_occupancy;
} mp4_VOLControlParameters_t;
/* Video Object Plane with short header Info */
typedef struct _mp4_VideoObjectPlaneH263
{
uint8_t temporal_reference;
uint8_t split_screen_indicator;
uint8_t document_camera_indicator;
uint8_t full_picture_freeze_release;
uint8_t source_format;
uint8_t picture_coding_type;
uint8_t vop_quant;
uint16_t num_gobs_in_vop;
uint16_t num_macroblocks_in_gob;
uint8_t num_rows_in_gob;
#if 0
uint8_t gob_number;
int gob_header_empty;
int gob_frame_id;
int quant_scale;
#endif
} mp4_VideoObjectPlaneH263;
typedef struct
{
uint16_t sprite_width;
uint16_t sprite_height;
uint16_t sprite_left_coordinate;
uint16_t sprite_top_coordinate;
uint16_t no_of_sprite_warping_points;
uint16_t sprite_warping_accuracy;
uint16_t sprite_brightness_change;
uint16_t low_latency_sprite_enable;
}mp4_VOLSpriteInfo_t;
typedef struct
{
uint8_t load_intra_quant_mat;
uint8_t load_nonintra_quant_mat;
uint16_t align_dummy1;
uint8_t intra_quant_mat[64];
uint8_t nonintra_quant_mat[64];
}mp4_VOLQuant_mat_t;
/* Video Object Layer Info */
typedef struct
{
uint8_t video_object_layer_id; /* Last 4 bits of start code. */
uint8_t short_video_header;
uint8_t random_accessible_vol;
uint8_t video_object_type_indication;
uint8_t is_object_layer_identifier;
uint8_t video_object_layer_verid;
uint8_t video_object_layer_priority;
uint8_t aspect_ratio_info;
uint8_t aspect_ratio_info_par_width;
uint8_t aspect_ratio_info_par_height;
uint8_t align_dummy1;
uint8_t is_vol_control_parameters;
mp4_VOLControlParameters_t VOLControlParameters;
uint8_t video_object_layer_shape;
uint16_t vop_time_increment_resolution;
uint8_t vop_time_increment_resolution_bits;
uint8_t fixed_vop_rate;
uint16_t fixed_vop_time_increment;
uint16_t video_object_layer_width;
uint16_t video_object_layer_height;
uint8_t interlaced;
uint8_t obmc_disable;
uint8_t sprite_enable;
mp4_VOLSpriteInfo_t sprite_info;
uint8_t not_8_bit;
uint8_t quant_precision;
uint8_t bits_per_pixel;
uint8_t quant_type;
mp4_VOLQuant_mat_t quant_mat_info;
uint8_t quarter_sample;
uint8_t complexity_estimation_disable;
uint8_t resync_marker_disable;
uint8_t data_partitioned;
uint8_t reversible_vlc;
uint8_t newpred_enable;
uint8_t reduced_resolution_vop_enable; // verid != 1
uint8_t scalability;
uint8_t low_latency_sprite_enable;
mp4_GroupOfVideoObjectPlane_t GroupOfVideoObjectPlane;
mp4_VideoObjectPlane_t VideoObjectPlane;
mp4_VideoObjectPlaneH263 VideoObjectPlaneH263;
// for interlaced B-VOP direct mode
uint32_t Tframe;
// for B-VOP direct mode
uint32_t TRB, TRD;
// time increment of past and future VOP for B-VOP
uint32_t pastFrameTime, futureFrameTime;
// VOP global time
uint32_t vop_sync_time, vop_sync_time_b;
} mp4_VideoObjectLayer_t;
/* video_signal_type Info */
typedef struct
{
uint8_t is_video_signal_type;
uint8_t video_format;
uint8_t video_range;
uint8_t is_colour_description;
uint8_t colour_primaries;
uint8_t transfer_characteristics;
uint8_t matrix_coefficients;
} mp4_VideoSignalType_t;
typedef struct _mp4_Frame {
long long int time;
} mp4_Frame;
/* Visual Object Info */
typedef struct
{
uint8_t is_visual_object_identifier;
uint8_t visual_object_verid;
uint8_t visual_object_priority;
uint8_t visual_object_type;
mp4_VideoSignalType_t VideoSignalType;
mp4_VideoObjectLayer_t VideoObject;
mp4_Frame currentFrame; // current
mp4_Frame pastFrame; // reference in past
mp4_Frame futureFrame; // reference in future
} mp4_VisualObject_t;
/* Full Info */
typedef struct
{
mp4_VisualObject_t VisualObject;
uint8_t profile_and_level_indication;
} mp4_Info_t;
enum
{
MP4_SC_SEEN_INVALID = 0x0,
MP4_SC_SEEN_VOL = 0x1,
MP4_SC_SEEN_VOP = 0x2,
MP4_SC_SEEN_SVH = 0x4,
};
enum
{
MP4_BS_ERROR_NONE = (0 << 0),
MP4_BS_ERROR_HDR_PARSE = (1 << 0),
MP4_BS_ERROR_HDR_NONDEC = (1 << 1),
MP4_BS_ERROR_HDR_UNSUP = (1 << 2),
MP4_BS_ERROR_FRM_PARSE = (1 << 3),
MP4_BS_ERROR_FRM_NONDEC = (1 << 4),
MP4_BS_ERROR_FRM_UNSUP = (1 << 5),
};
#define MP4_HDR_ERROR_MASK (MP4_BS_ERROR_HDR_PARSE | MP4_BS_ERROR_HDR_NONDEC | MP4_BS_ERROR_HDR_UNSUP)
typedef enum
{
VIDDEC_MP4_INDX_0 = 0,
VIDDEC_MP4_INDX_1 = 1,
VIDDEC_MP4_INDX_2 = 2,
VIDDEC_MP4_INDX_MAX = 3,
} viddec_fw_mp4_ref_index_t;
typedef struct
{
uint8_t is_field;
} viddec_mp4_ref_info_t;
typedef struct
{
// The relevant bitstream data for current stream
mp4_Info_t info;
// The previous start code (without the prefix)
uint32_t prev_sc;
// The current start code (without the prefix)
// TODO: Revisit for SVH
uint32_t current_sc;
// Indicates if we look for both short and long video header or just the long video header
// If false, sc detection looks for both short and long video headers.
// If true, long video header has been seen and sc detection does not look for short video header any more.
uint8_t ignore_scs;
// Indicates if the current start code prefix is long (if true).
uint8_t cur_sc_prefix;
// Indicates if the next start code prefix is long (if true).
uint8_t next_sc_prefix;
// Indicates start of a frame
uint8_t is_frame_start;
// Indicates which start codes were seen for this workload
uint8_t sc_seen;
// Indicates bitstream errors if any
uint16_t bitstream_error;
// Reference frame information
viddec_mp4_ref_info_t ref_frame[VIDDEC_MP4_INDX_MAX];
}viddec_mp4_parser_t;
#define BREAK_GETBITS_FAIL(x, ret) { \
if(x == -1){ \
FWTRACE; \
ret = MP4_STATUS_PARSE_ERROR; \
break;} \
}
#define BREAK_GETBITS_REQD_MISSING(x, ret) { \
if(x == -1){ \
FWTRACE; \
ret = MP4_STATUS_REQD_DATA_ERROR; \
break;} \
}
extern void *memset(void *s, int32_t c, uint32_t n);
uint32_t viddec_fw_mp4_emit_workload(void *parent, void *ctxt);
void mp4_set_hdr_bitstream_error(viddec_mp4_parser_t *parser, uint8_t hdr_flag, mp4_Status_t parse_status);
#endif