1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/** 2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * viddec_mpeg2_parse.c 3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * -------------------- 4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * This file acts as the main interface between the parser manager and MPEG2 5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * parser. All the operations done by the MPEG2 parser are defined here and 6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * functions pointers for each operation is returned to the parser manager. 7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */ 8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mpeg2.h" 10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_parser_init() - Initializes parser context. */ 12bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_parser_init 13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *ctxt, 15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t *persist_mem, 16bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t preserve 17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 18bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt; 20bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Avoid compiler warning */ 22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee persist_mem = persist_mem; 23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Initialize state variables */ 25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_pic_metadata_complete = false; 26bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_picture_interlaced = false; 27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_first_field = false; 28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_frame_start = false; 29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_ref_table_updated = false; 30bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_use_next_workload = false; 31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_first_slice_flag = false; 32bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_curr_frame_headers = MPEG2_HEADER_NONE; 33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_last_parsed_sc = MPEG2_SC_ALL; 34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_last_parsed_slice_sc = MPEG2_SC_SLICE_MAX; 35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_wl_status = MPEG2_WL_EMPTY; 36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_prev_picture_structure = MPEG2_PIC_STRUCT_FRAME; 37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_prev_temp_ref = 0; 38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_num_pan_scan_offsets = 0; 39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if(preserve) 41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Init all picture level header info */ 43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee memset(&parser->info.pic_hdr, 0, sizeof(struct mpeg2_picture_hdr_info)); 44bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee memset(&parser->info.pic_cod_ext, 0, sizeof(struct mpeg2_picture_coding_ext_info)); 45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee memset(&parser->info.pic_disp_ext, 0, sizeof(struct mpeg2_picture_disp_ext_info)); 46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee else 48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Init all header info */ 50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee memset(&parser->info, 0, sizeof(struct mpeg2_info)); 51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_stream = false; 53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_custom_qmat_parsed = false; 54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_valid_seq_hdr_parsed = false; 55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_curr_seq_headers = MPEG2_HEADER_NONE; 56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee MPEG2_DEB("MPEG2 Parser: Context Initialized.\n"); 59bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return; 61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_context_size() - Returns the memory size required by the */ 64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* MPEG2 parser. */ 65bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_get_context_size 66bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_parser_memory_sizes_t *size 68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Should return size of my structure */ 71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee size->context_size = sizeof(struct viddec_mpeg2_parser); 72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee size->persist_size = 0; 73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_error_code() - Returns the error code for the current */ 76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* workload. */ 77bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_get_error_code 78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 79bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee struct viddec_mpeg2_parser *parser, 80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_workload_t *wl, 81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t *error_code 82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 84bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code = 0; 85bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Dangling field error */ 87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_DANGLING_FIELD) 88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_WORKLOAD_ERR_DANGLING_FLD; 90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_DANGLING_FIELD_TOP) 91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_WORKLOAD_ERR_TOPFIELD; 93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee else 95bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_WORKLOAD_ERR_BOTTOMFIELD; 97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Repeated same field */ 101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_REPEAT_FIELD) 102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= (VIDDEC_FW_WORKLOAD_ERR_DANGLING_FLD 104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE); 105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* If workload is not complete, set non-decodeable flag */ 108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!(parser->mpeg2_wl_status & MPEG2_WL_COMPLETE)) 109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* If reference info is not updated, set missing reference flag */ 114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!(parser->mpeg2_wl_status & MPEG2_WL_REF_INFO)) 115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_WORKLOAD_ERR_MISSING_REFERENCE; 117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Missing DMEM data flag and irrecoverable flag is set */ 120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!(parser->mpeg2_wl_status & MPEG2_WL_DMEM_DATA)) 121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_MISSING_DMEM 123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ; 124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Missing sequence header and irrecoverable flag is set */ 127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if ((!(parser->mpeg2_curr_seq_headers & MPEG2_HEADER_SEQ)) 128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee && (!parser->mpeg2_valid_seq_hdr_parsed)) 129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_MISSING_SEQ_INFO 131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ; 132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Unsupported features found in stream */ 135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_UNSUPPORTED) 136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_UNSUPPORTED 138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ; 139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* If frame type is unknown, default to I frame. */ 142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if ((wl->attrs.frame_type != VIDDEC_FRAME_TYPE_I) 143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee && (wl->attrs.frame_type != VIDDEC_FRAME_TYPE_P) 144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee && (wl->attrs.frame_type != VIDDEC_FRAME_TYPE_B)) 145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee wl->attrs.frame_type = VIDDEC_FRAME_TYPE_I; 147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* If there is a mismatch between the frame type and reference information */ 150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* then mark the workload as not decodable */ 151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (wl->attrs.frame_type == VIDDEC_FRAME_TYPE_B) 152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (wl->is_reference_frame != 0) *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee else 156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (wl->is_reference_frame == 0) *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* For non-decodable frames, do not set reference info so that the workload */ 161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* manager does not increment ref count. */ 162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (*error_code & VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE) 163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee wl->is_reference_frame = 0; 165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Corrupted header notification */ 168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_HDR) 169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_HDR; 170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_EXT) 171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_EXT; 172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_DISP_EXT) 173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_DISP_EXT; 174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_GOP_HDR) 175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_GOP_HDR; 176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_HDR) 177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_HDR; 178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_COD_EXT) 179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_COD_EXT; 180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_DISP_EXT) 181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_DISP_EXT; 182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_QMAT_EXT) 183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_QMAT_EXT; 184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee MPEG2_DEB("Workload error code: 0x%8X.\n", *error_code); 186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return; 187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_is_start_frame() - Returns if the current chunk of parsed */ 190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* data has start of a frame. */ 191bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic uint32_t viddec_mpeg2_is_start_frame 192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *ctxt 194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt; 197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return (parser->mpeg2_frame_start); 198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_is_workload_done() - Returns current frame parsing status */ 201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* to the parser manager. */ 202bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic uint32_t viddec_mpeg2_is_workload_done 203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *parent, 205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *ctxt, 206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee unsigned int next_sc, 207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t *codec_specific_errors 208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt; 211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_workload_t *wl = viddec_pm_get_header(parent); 212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t ret = VIDDEC_PARSE_SUCESS; 213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t frame_boundary = 0; 214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint8_t force_frame_complete = 0; 215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parent = parent; 216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Detect Frame Boundary */ 218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee frame_boundary = ((MPEG2_SC_PICTURE == next_sc) || (MPEG2_SC_SEQ_HDR == next_sc) || (MPEG2_SC_GROUP == next_sc)); 219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (frame_boundary) 220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_first_slice_flag = false; 222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee force_frame_complete = ((VIDDEC_PARSE_EOS == next_sc) || (VIDDEC_PARSE_DISCONTINUITY == next_sc)); 225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (force_frame_complete || (frame_boundary && (parser->mpeg2_pic_metadata_complete))) 227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if(!force_frame_complete) 229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_wl_status |= MPEG2_WL_COMPLETE; 231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_last_parsed_slice_sc = MPEG2_SC_SLICE_MAX; 232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_pic_metadata_complete = false; 233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_first_slice_flag = false; 234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_get_error_code(parser, wl, codec_specific_errors); 237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_wl_status = MPEG2_WL_EMPTY; 238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_curr_frame_headers = MPEG2_HEADER_NONE; 239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Reset mpeg2_use_next_workload flag if it is set */ 240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (parser->mpeg2_use_next_workload) 241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_pm_set_late_frame_detect(parent); 243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_use_next_workload = false; 244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ret = VIDDEC_PARSE_FRMDONE; 246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return ret; 248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_parse() - Parse metadata info from the buffer for the prev */ 251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* start code found. */ 252bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic mpeg2_status viddec_mpeg2_parse 253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *parent, 255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee void *ctxt 256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee uint32_t current_sc = 0, sc_bits = MPEG2_SC_AND_PREFIX_SIZE; 259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int32_t ret = MPEG2_SUCCESS; 260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt; 261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Reset frame start flag. For Mpeg1 we want to set frame start after 263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee we parsed pich header, since there is no extension*/ 264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_frame_start = (!parser->mpeg2_stream) && (parser->mpeg2_last_parsed_sc == MPEG2_SC_PICTURE); 265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Peak current start code - First 32 bits of the stream */ 267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ret = viddec_pm_peek_bits(parent, ¤t_sc, sc_bits); 268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (ret == -1) 269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee MPEG2_DEB("Unable to get start code.\n"); 271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return MPEG2_PARSE_ERROR; 272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee current_sc &= MPEG2_BIT_MASK_8; 274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee MPEG2_DEB("Start Code found = 0x%.8X\n", current_sc); 275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Get rid of the start code prefix for all start codes except slice */ 277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* start codes. */ 278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if ((current_sc < MPEG2_SC_SLICE_MIN) || (current_sc > MPEG2_SC_SLICE_MAX)) 279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_pm_skip_bits(parent, sc_bits); 281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 283bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Parse Metadata based on the start code found */ 284bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee switch( current_sc ) 285bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 286bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Sequence Start Code */ 287bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_SEQ_HDR: 288bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 289bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_curr_seq_headers = MPEG2_HEADER_NONE; 290bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_seq_hdr(parent, ctxt); 291bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 292bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 293bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 294bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Picture Start Code */ 295bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_PICTURE: 296bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 297bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_pic_hdr(parent, ctxt); 298bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 299bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 300bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 301bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Extension Code */ 302bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_EXT: 303bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 304bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_ext(parent, ctxt); 305bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 306bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 307bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 308bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Group of Pictures Header */ 309bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_GROUP: 310bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 311bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_gop_hdr(parent, ctxt); 312bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 313bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 314bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 315bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Unused Start Code */ 316bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_SEQ_END: 317bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_SEQ_ERR: 318bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 319bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 320bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* User Data */ 321bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee case MPEG2_SC_USER_DATA: 322bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 323bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_and_append_user_data(parent, ctxt); 324bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 325bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee break; 326bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 327bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee default: 328bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 329bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Slice Data - Append slice data to the workload */ 330bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if ((current_sc >= MPEG2_SC_SLICE_MIN) && 331bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee (current_sc <= MPEG2_SC_SLICE_MAX)) 332bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 333bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!parser->mpeg2_first_slice_flag) 334bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 335bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* At this point, all the metadata required by the MPEG2 */ 336bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* hardware for decoding is extracted and stored. So the */ 337bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* metadata can be packed into workitems and emitted out.*/ 338bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_emit_workload(parent, ctxt); 339bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 340bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* If the current picture is progressive or it is the */ 341bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* second field of interlaced field picture then, set */ 342bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* the workload done flag. */ 343bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if ((!parser->mpeg2_picture_interlaced) 344bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee || ((parser->mpeg2_picture_interlaced) && (!parser->mpeg2_first_field))) 345bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 346bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_pic_metadata_complete = true; 347bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 348bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee else if ((parser->mpeg2_picture_interlaced) && (parser->mpeg2_first_field)) 349bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee { 350bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_curr_frame_headers = MPEG2_HEADER_NONE; 351bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 352bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 353bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_first_slice_flag = true; 354bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 355bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_last_parsed_slice_sc = current_sc; 356bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_mpeg2_parse_and_append_slice_data(parent, ctxt); 357bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_wl_status |= MPEG2_WL_PARTIAL_SLICE; 358bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 359bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 360bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } /* Switch */ 361bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 362bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee /* Save last parsed start code */ 363bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee parser->mpeg2_last_parsed_sc = current_sc; 364bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return ret; 365bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 366bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 367bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_ops() - Register parser ops with the parser manager. */ 368bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid viddec_mpeg2_get_ops 369bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee( 370bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee viddec_parser_ops_t *ops 371bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee) 372bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{ 373bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ops->init = viddec_mpeg2_parser_init; 374bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ops->parse_syntax = viddec_mpeg2_parse; 375bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ops->get_cxt_size = viddec_mpeg2_get_context_size; 376bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ops->is_wkld_done = viddec_mpeg2_is_workload_done; 377bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ops->is_frame_start = viddec_mpeg2_is_start_frame; 378bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return; 379bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 380bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 381