OMX_ERRORTYPE omx_vdec::get_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { if (ext->nIndex >= mVendorExtensionStore.size()) { return OMX_ErrorNoMore; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: getConfig: index=%u (%s)", ext->nIndex, vExt.name()); vExt.copyInfoTo(ext); if (ext->nParamSizeUsed < vExt.paramCount()) { // this happens during initial getConfig to query only extension-name and param-count return OMX_ErrorNone; } // We now have sufficient params allocated in extension data passed. // Following code is to set the extension-specific data bool setStatus = true; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_QcomIndexParamVideoDecoderPictureOrder: { setStatus &= vExt.setParamInt32(ext, "enable", m_decode_order_mode); break; } default: { return OMX_ErrorNotImplemented; } } return setStatus ? OMX_ErrorNone : OMX_ErrorUndefined; }
OMX_ERRORTYPE omx_video::get_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { if (ext->nIndex >= mVendorExtensionStore.size()) { return OMX_ErrorNoMore; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: getConfig: index=%u (%s)", ext->nIndex, vExt.name()); vExt.copyInfoTo(ext); if (ext->nParamSizeUsed < vExt.paramCount()) { // this happens during initial getConfig to query only extension-name and param-count return OMX_ErrorNone; } // We now have sufficient params allocated in extension data passed. // Following code is to set the extension-specific data bool setStatus = true; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_IndexConfigCommonRotate: { setStatus &= vExt.setParamInt32(ext, "angle", m_sConfigFrameRotation.nRotation); break; } case OMX_IndexConfigVideoAVCIntraPeriod: { setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sConfigAVCIDRPeriod.nPFrames); setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sConfigAVCIDRPeriod.nIDRPeriod); break; } case OMX_IndexParamVideoErrorCorrection: { // "bits" @0 setStatus &= vExt.setParamInt32(ext, "resync-marker-spacing-bits", m_sErrorCorrection.nResynchMarkerSpacing); break; } case OMX_IndexParamVideoProfileLevelCurrent: { setStatus &= vExt.setParamInt32(ext, "profile", m_sParamProfileLevel.eProfile); setStatus &= vExt.setParamInt32(ext, "level", m_sParamProfileLevel.eLevel); break; } case OMX_QTIIndexParamEnableAVTimerTimestamps: { setStatus &= vExt.setParamInt32(ext, "enable", m_sParamAVTimerTimestampMode.bEnable); break; } default: { return OMX_ErrorNotImplemented; } } return setStatus ? OMX_ErrorNone : OMX_ErrorUndefined; }
OMX_ERRORTYPE omx_vdec::set_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { ALOGI("set_vendor_extension_config"); if (ext->nIndex >= mVendorExtensionStore.size()) { DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", ext->nIndex, mVendorExtensionStore.size()); return OMX_ErrorBadParameter; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); OMX_ERRORTYPE err = OMX_ErrorNone; err = vExt.isConfigValid(ext); if (err != OMX_ErrorNone) { return err; } // mark this as set, regardless of set_config succeeding/failing. // App will know by inconsistent values in output-format vExt.set(); bool valueSet = false; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_QcomIndexParamVideoDecoderPictureOrder: { OMX_S32 pic_order_enable = 0; valueSet |= vExt.readParamInt32(ext, "enable", &pic_order_enable); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_QcomIndexParamVideoDecoderPictureOrder : %d", pic_order_enable); QOMX_VIDEO_DECODER_PICTURE_ORDER decParam; OMX_INIT_STRUCT(&decParam, QOMX_VIDEO_DECODER_PICTURE_ORDER); decParam.eOutputPictureOrder = pic_order_enable ? QOMX_VIDEO_DECODE_ORDER : QOMX_VIDEO_DISPLAY_ORDER; err = set_parameter( NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder, &decParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexParamVideoDecoderPictureOrder failed !"); } break; } default: { return OMX_ErrorNotImplemented; } } return err; }
bool omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, int dest_fd, void *dest_base, void *dest_viraddr) { int result; if(!src_viraddr || !dest_viraddr || !c2dcc){ DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); return false; } result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, dest_fd, dest_base, dest_viraddr); DEBUG_PRINT_LOW("\n Color convert status %d",result); return ((result < 0)?false:true); }
bool omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) { int cret = 0; bool ret = false; C2DBuffReq bufferreq; if(c2dcc){ bufferreq.size = 0; cret = c2dcc->getBuffReq(port,&bufferreq); DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); ret = (cret)?false:true; buf_size = bufferreq.size; } return ret; }
int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, OMX_BUFFERHEADERTYPE *dest , OMX_U32 *partialframe) { OMX_U8 *pdest = NULL,*psource = NULL; OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0; if (source == NULL || dest == NULL || partialframe == NULL) { return -1; } /*Calculate the length's*/ dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; if (dest_len < 4 || source_len == 0 || nal_length == 0) { DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d " "source_len %d nal_length %d", dest_len, source_len, nal_length); return -1; } *partialframe = 1; temp_len = (source_len < dest_len)?source_len:dest_len; psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); /* Find the Bytes to Accumalte*/ if (state_nal == NAL_LENGTH_ACC) { while (parsed_length < temp_len ) { bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3)); /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/ //*pdest = *psource; accum_length++; source->nFilledLen--; source->nOffset++; psource++; //dest->nFilledLen++; //pdest++; parsed_length++; if (accum_length == nal_length) { accum_length = 0; state_nal = NAL_PARSING; memcpy (pdest,H264_start_code,4); dest->nFilledLen += 4; break; } } } dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; temp_len = (source_len < dest_len)?source_len:dest_len; psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); dest->nTimeStamp = source->nTimeStamp; dest->nFlags = source->nFlags; /*Already in Parsing state go ahead and copy*/ if (state_nal == NAL_PARSING && temp_len > 0) { if (temp_len < bytes_tobeparsed) { memcpy (pdest,psource,temp_len); dest->nFilledLen += temp_len; source->nOffset += temp_len; source->nFilledLen -= temp_len; bytes_tobeparsed -= temp_len; } else { memcpy (pdest,psource,bytes_tobeparsed); temp_len -= bytes_tobeparsed; dest->nFilledLen += bytes_tobeparsed; source->nOffset += bytes_tobeparsed; source->nFilledLen -= bytes_tobeparsed; bytes_tobeparsed = 0; } } if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) { *partialframe = 0; state_nal = NAL_LENGTH_ACC; } return 1; }
int frame_parse::parse_sc_frame ( OMX_BUFFERHEADERTYPE *source, OMX_BUFFERHEADERTYPE *dest , OMX_U32 *partialframe) { OMX_U8 *pdest = NULL,*psource = NULL, match_found = FALSE, is_byte_match = 0; OMX_U32 dest_len =0, source_len = 0, temp_len = 0; OMX_U32 parsed_length = 0,i=0; int residue_byte = 0; if (source == NULL || dest == NULL || partialframe == NULL) { return -1; } /*Calculate how many bytes are left in source and destination*/ dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; /*Need Minimum Start Code size for destination to copy atleast Start code*/ if ((start_code == H263_start_code && dest_len < 3) || (start_code != H263_start_code && dest_len < 4) || (source_len == 0)) { DEBUG_PRINT_LOW("\n FrameParser: dest_len %d source_len %d",dest_len,source_len); if (source_len == 0 && (source->nFlags & 0x01)) { DEBUG_PRINT_LOW("\n FrameParser: EOS rxd!! Notify it as a complete frame"); *partialframe = 0; return 1; } DEBUG_PRINT_LOW("\n FrameParser: Bitstream Parsing error"); return -1; } /*Check if State of the previous find is a Start code*/ if (parse_state == A4 || parse_state == A5) { /*Check for minimun size should be 4*/ dest->nFlags = source->nFlags; dest->nTimeStamp = source->nTimeStamp; if (start_code == H263_start_code) { memcpy (pdest,start_code,2); pdest[2] = last_byte_h263; dest->nFilledLen += 3; pdest += 3; } else { memcpy (pdest,start_code,4); if (start_code == VC1_AP_start_code || start_code == MPEG4_start_code || start_code == MPEG2_start_code) { pdest[3] = last_byte; update_skip_frame(); } dest->nFilledLen += 4; pdest += 4; } parse_state = A0; } /*Entry State Machine*/ while ( source->nFilledLen > 0 && parse_state != A0 && parse_state != A4 && parse_state != A5 && dest_len > 0 ) { //printf ("\n In the Entry Loop"); switch (parse_state) { case A3: parse_additional_start_code(psource,&parsed_length); if (parse_state == A4) { source->nFilledLen--; source->nOffset++; psource++; break; } /*If fourth Byte is matching then start code is found*/ if ((*psource & mask_code [3]) == start_code [3]) { parse_state = A4; last_byte = *psource; source->nFilledLen--; source->nOffset++; psource++; } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) { parse_state = A2; memcpy (pdest,start_code,1); pdest++; dest->nFilledLen++; dest_len--; } else if (start_code [2] == start_code [0]) { parse_state = A1; memcpy (pdest,start_code,2); pdest += 2; dest->nFilledLen += 2; dest_len -= 2; } else { parse_state = A0; memcpy (pdest,start_code,3); pdest += 3; dest->nFilledLen +=3; dest_len -= 3; } break; case A2: is_byte_match = ((*psource & mask_code [2]) == start_code [2]); match_found = FALSE; if (start_code == H263_start_code) { if (is_byte_match) { last_byte_h263 = *psource; parse_state = A5; match_found = TRUE; } } else if (start_code == H264_start_code && (*psource & mask_code [3]) == start_code [3]) { parse_state = A5; match_found = TRUE; } else { if (is_byte_match) { parse_state = A3; match_found = TRUE; } } if (match_found) { source->nFilledLen--; source->nOffset++; psource++; } else if (start_code [1] == start_code [0]) { parse_state = A1; memcpy (pdest,start_code,1); dest->nFilledLen +=1; dest_len--; pdest++; } else { parse_state = A0; memcpy (pdest,start_code,2); dest->nFilledLen +=2; dest_len -= 2; pdest += 2; } break; case A1: if ((*psource & mask_code [1]) == start_code [1]) { parse_state = A2; source->nFilledLen--; source->nOffset++; psource++; } else { memcpy (pdest,start_code,1); dest->nFilledLen +=1; pdest++; dest_len--; parse_state = A0; } break; case A4: case A0: case A5: break; } dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); } if (parse_state == A4 || parse_state == A5) { *partialframe = 0; check_skip_frame_boundary(partialframe); DEBUG_PRINT_LOW("\n FrameParser: Parsed Len = %d", dest->nFilledLen); return 1; } /*Partial Frame is true*/ *partialframe = 1; /*Calculate how many bytes are left in source and destination*/ dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; temp_len = (source_len < dest_len)?source_len:dest_len; /*Check if entry state machine consumed source or destination*/ if (temp_len == 0) { return 1; } /*Parsing State Machine*/ while (parsed_length < temp_len) { switch (parse_state) { case A0: if ((psource [parsed_length] & mask_code [0]) == start_code[0]) { parse_state = A1; } parsed_length++; break; case A1: if ((psource [parsed_length] & mask_code [1]) == start_code [1]) { parsed_length++; parse_state = A2; } else { parse_state = A0; } break; case A2: is_byte_match = ((psource[parsed_length] & mask_code [2]) == start_code [2]); match_found = FALSE; if (start_code == H263_start_code) { if (is_byte_match) { last_byte_h263 = psource[parsed_length]; parse_state = A5; match_found = TRUE; } } else if (start_code == H264_start_code && (psource[parsed_length] & mask_code [3]) == start_code [3]) { parse_state = A5; match_found = TRUE; } else { if (is_byte_match) { parse_state = A3; match_found = TRUE; } } if (match_found) { parsed_length++; } else if (start_code [1] == start_code [0]) { parse_state = A1; } else { parse_state = A0; } break; case A3: parse_additional_start_code(psource,&parsed_length); if (parse_state == A4) break; if ((psource [parsed_length] & mask_code [3]) == start_code [3]) { last_byte = psource [parsed_length]; parsed_length++; parse_state = A4; } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) { parse_state = A2; } else if (start_code [2] == start_code [0]) { parse_state = A1; } else { parse_state = A0; } break; case A4: case A5: break; } /*Found the code break*/ if (parse_state == A4 || parse_state == A5) { break; } } /*Exit State Machine*/ psource = source->pBuffer + source->nOffset; int bytes_to_skip = 0; switch (parse_state) { case A5: *partialframe = 0; check_skip_frame_boundary(partialframe); bytes_to_skip = 3; break; case A4: *partialframe = 0; check_skip_frame_boundary(partialframe); bytes_to_skip = 4; break; case A3: if (source->nFlags & OMX_BUFFERFLAG_EOS) { bytes_to_skip = 0; } else { bytes_to_skip = 3; } break; case A2: if (source->nFlags & OMX_BUFFERFLAG_EOS) { bytes_to_skip = 0; } else { bytes_to_skip = 2; } break; case A1: if (source->nFlags & OMX_BUFFERFLAG_EOS) { bytes_to_skip = 0; } else { bytes_to_skip = 1; } break; case A0: bytes_to_skip = 0; break; } if (source->nFilledLen < parsed_length) { printf ("\n FATAL Error"); return -1; } if (parsed_length > bytes_to_skip) { memcpy (pdest, psource, (parsed_length-bytes_to_skip)); dest->nFilledLen += (parsed_length-bytes_to_skip); } source->nFilledLen -= parsed_length; source->nOffset += parsed_length; return 1; }
OMX_ERRORTYPE omx_video::set_vendor_extension_config( OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) { ALOGI("set_vendor_extension_config"); if (ext->nIndex >= mVendorExtensionStore.size()) { DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)", ext->nIndex, mVendorExtensionStore.size()); return OMX_ErrorBadParameter; } const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex]; DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name()); OMX_ERRORTYPE err = OMX_ErrorNone; err = vExt.isConfigValid(ext); if (err != OMX_ErrorNone) { return err; } // mark this as set, regardless of set_config succeeding/failing. // App will know by inconsistent values in output-format vExt.set(); bool valueSet = false; switch ((OMX_U32)vExt.extensionIndex()) { case OMX_IndexConfigCommonRotate: { OMX_CONFIG_ROTATIONTYPE rotationParam; memcpy(&rotationParam, &m_sConfigFrameRotation, sizeof(OMX_CONFIG_ROTATIONTYPE)); valueSet |= vExt.readParamInt32(ext, "angle", &rotationParam.nRotation); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigCommonRotate : %d", rotationParam.nRotation); err = set_config( NULL, OMX_IndexConfigCommonRotate, &rotationParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigCommonRotate failed !"); } break; } case OMX_IndexConfigVideoAVCIntraPeriod: { OMX_VIDEO_CONFIG_AVCINTRAPERIOD idrConfig; memcpy(&idrConfig, &m_sConfigAVCIDRPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD)); valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(idrConfig.nPFrames)); valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(idrConfig.nIDRPeriod)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d", idrConfig.nPFrames, idrConfig.nIDRPeriod); err = set_config( NULL, OMX_IndexConfigVideoAVCIntraPeriod, &idrConfig); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigVideoAVCIntraPeriod failed !"); } break; } case OMX_IndexParamVideoErrorCorrection: { OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE ecParam; memcpy(&ecParam, &m_sErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); valueSet |= vExt.readParamInt32(ext, "resync-marker-spacing-bits", (OMX_S32 *)&(ecParam.nResynchMarkerSpacing)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: resync-marker-spacing : %d bits", ecParam.nResynchMarkerSpacing); err = set_parameter( NULL, OMX_IndexParamVideoErrorCorrection, &ecParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoErrorCorrection failed !"); } break; } case OMX_IndexParamVideoProfileLevelCurrent: { OMX_VIDEO_PARAM_PROFILELEVELTYPE profileParam; memcpy(&profileParam, &m_sParamProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); valueSet |= vExt.readParamInt32(ext, "profile", (OMX_S32 *)&(profileParam.eProfile)); valueSet |= vExt.readParamInt32(ext, "level", (OMX_S32 *)&(profileParam.eLevel)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: custom-profile/level : profile=%u level=%u", (OMX_U32)profileParam.eProfile, (OMX_U32)profileParam.eLevel); err = set_parameter( NULL, OMX_IndexParamVideoProfileLevelCurrent, &profileParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoProfileLevelCurrent failed !"); } break; } case OMX_QTIIndexParamEnableAVTimerTimestamps: { QOMX_ENABLETYPE avTimerEnableParam; memcpy(&avTimerEnableParam, &m_sParamAVTimerTimestampMode, sizeof(QOMX_ENABLETYPE)); valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(avTimerEnableParam.bEnable)); if (!valueSet) { break; } DEBUG_PRINT_HIGH("VENDOR-EXT: AV-timer timestamp mode enable=%u", avTimerEnableParam.bEnable); err = set_parameter( NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamEnableAVTimerTimestamps, &avTimerEnableParam); if (err != OMX_ErrorNone) { DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamEnableAVTimerTimestamps failed !"); } break; } default: { return OMX_ErrorNotImplemented; } } return err; }
/*=========================================================================== FUNCTION: HEVC_Utils::iSNewFrame DESCRIPTION: Returns true if NAL parsing successfull otherwise false. INPUT/OUTPUT PARAMETERS: <In> buffer : buffer containing start code or nal length + NAL units buffer_length : the length of the NAL buffer start_code : If true, start code is detected, otherwise size nal length is detected size_of_nal_length_field: size of nal length field <out> isNewFrame: true if the NAL belongs to a differenet frame false if the NAL belongs to a current frame RETURN VALUE: boolean true, if nal parsing is successful false, if the nal parsing has errors SIDE EFFECTS: None. ===========================================================================*/ bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, OMX_IN OMX_U32 size_of_nal_length_field, OMX_OUT OMX_BOOL &isNewFrame) { OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; byte bFirstSliceInPic = 0; byte coef1=1, coef2=0, coef3=0; uint32 pos = 0; uint32 nal_len = buffer_length; uint32 sizeofNalLengthField = 0; uint32 zero_count; boolean start_code = (size_of_nal_length_field==0)?true:false; if (start_code) { // Search start_code_prefix_one_3bytes (0x000001) coef2 = buffer[pos++]; coef3 = buffer[pos++]; do { if (pos >= buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } coef1 = coef2; coef2 = coef3; coef3 = buffer[pos++]; } while (coef1 || coef2 || coef3 != 1); } else if (size_of_nal_length_field) { /* This is the case to play multiple NAL units inside each access unit*/ /* Extract the NAL length depending on sizeOfNALength field */ sizeofNalLengthField = size_of_nal_length_field; nal_len = 0; while (size_of_nal_length_field--) { nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); } if (nal_len >= buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } } if (nal_len > buffer_length) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } if (pos + 2 > (nal_len + sizeofNalLengthField)) { DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); return false; } nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type DEBUG_PRINT_LOW("@#@# Pos = %x NalType = %x buflen = %u", pos-1, nalu_type, (unsigned int) buffer_length); isNewFrame = OMX_FALSE; if (nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_SEI) { DEBUG_PRINT_LOW("Non-AU boundary with NAL type %d", nalu_type); if (m_au_data) { isNewFrame = OMX_TRUE; m_au_data = false; } m_forceToStichNextNAL = true; } else if (nalu_type <= NAL_UNIT_RESERVED_23) { DEBUG_PRINT_LOW("AU Boundary with NAL type %d ", nalu_type); if (!m_forceToStichNextNAL) { bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7); if (bFirstSliceInPic) { //=== first_ctb_in_slice is only 1'b1 coded tree block DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block"); isNewFrame = OMX_TRUE; } }
int frame_parse::parse_mpeg4_frame ( OMX_BUFFERHEADERTYPE *source, OMX_BUFFERHEADERTYPE *dest , OMX_U32 *partialframe) { OMX_U8 *pdest = NULL,*psource = NULL; OMX_U32 dest_len =0, source_len = 0, temp_len = 0; OMX_U32 parsed_length = 0,i=0; int residue_byte = 0; if (source == NULL || dest == NULL || partialframe == NULL) { return -1; } /*Calculate how many bytes are left in source and destination*/ dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; /*Need Minimum of 4 for destination to copy atleast Start code*/ if (dest_len < 4 || source_len == 0) { DEBUG_PRINT_LOW("\n Dest_len %d source_len %d",dest_len,source_len); if (source_len == 0 && (source->nFlags & 0x01)) { DEBUG_PRINT_LOW("\n EOS condition Inform Client that it is complete frame"); *partialframe = 0; return 1; } DEBUG_PRINT_LOW("\n Error in Parsing bitstream"); return -1; } /*Check if State of the previous find is a Start code*/ if (parse_state == A4) { /*Check for minimun size should be 4*/ dest->nFlags = flags; dest->nTimeStamp = time_stamp; update_metadata(source->nTimeStamp,source->nFlags); memcpy (pdest,start_code,4); pdest [2] = prev_one; pdest [3] = last_byte; dest->nFilledLen += 4; pdest += 4; parse_state = A0; } /*Entry State Machine*/ while ( source->nFilledLen > 0 && parse_state != A0 && parse_state != A4 && dest_len > 0 ) { //printf ("\n In the Entry Loop"); switch (parse_state) { case A3: /*If fourth Byte is matching then start code is found*/ if ((*psource & mask_code [3]) == start_code [3]) { last_byte = *psource; parse_state = A4; source->nFilledLen--; source->nOffset++; psource++; } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) { parse_state = A2; memcpy (pdest,start_code,1); pdest++; dest->nFilledLen++; dest_len--; } else if (start_code [2] == start_code [0]) { parse_state = A1; memcpy (pdest,start_code,2); pdest += 2; dest->nFilledLen += 2; dest_len -= 2; } else { parse_state = A0; memcpy (pdest,start_code,3); pdest += 3; dest->nFilledLen +=3; dest_len -= 3; } break; case A2: if ((*psource & mask_code [2]) == start_code [2]) { prev_one = *psource; parse_state = A3; source->nFilledLen--; source->nOffset++; psource++; } else if ( start_code [1] == start_code [0]) { parse_state = A1; memcpy (pdest,start_code,1); dest->nFilledLen +=1; dest_len--; pdest++; } else { parse_state = A0; memcpy (pdest,start_code,2); dest->nFilledLen +=2; dest_len -= 2; pdest += 2; } break; case A1: if ((*psource & mask_code [1]) == start_code [1]) { parse_state = A2; source->nFilledLen--; source->nOffset++; psource++; } else { memcpy (pdest,start_code,1); dest->nFilledLen +=1; pdest++; dest_len--; parse_state = A0; } break; case A4: case A0: break; } dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); } if (parse_state == A4) { *partialframe = 0; DEBUG_PRINT_LOW("\n Nal Found length is %d",dest->nFilledLen); return 1; } /*Partial Frame is true*/ *partialframe = 1; /*Calculate how many bytes are left in source and destination*/ dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); psource = source->pBuffer + source->nOffset; pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); source_len = source->nFilledLen; temp_len = (source_len < dest_len)?source_len:dest_len; /*Check if entry state machine consumed source or destination*/ if (temp_len == 0) { return 1; } /*Parsing State Machine*/ while (parsed_length < temp_len) { switch (parse_state) { case A0: if ((psource [parsed_length] & mask_code [0]) == start_code[0]) { parse_state = A1; } parsed_length++; break; case A1: if ((psource [parsed_length] & mask_code [1]) == start_code [1]) { parsed_length++; parse_state = A2; } else { parse_state = A0; } break; case A2: if ((psource [parsed_length] & mask_code [2]) == start_code [2]) { prev_one = psource [parsed_length]; parsed_length++; parse_state = A3; } else if (start_code [1] == start_code [0]) { parse_state = A1; } else { parse_state = A0; } break; case A3: if ((psource [parsed_length] & mask_code [3]) == start_code [3]) { last_byte = psource [parsed_length]; parsed_length++; parse_state = A4; } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) { parse_state = A2; } else if (start_code [2] == start_code [0]) { parse_state = A1; } else { parse_state = A0; } break; default: break; } /*Found the code break*/ if (parse_state == A4) { break; } } /*Exit State Machine*/ psource = source->pBuffer + source->nOffset; switch (parse_state) { case A4: *partialframe = 0; if (parsed_length > 4) { memcpy (pdest,psource,(parsed_length-4)); dest->nFilledLen += (parsed_length-4); } break; case A3: if (parsed_length > 3) { memcpy (pdest,psource,(parsed_length-3)); dest->nFilledLen += (parsed_length-3); } break; case A2: if (parsed_length > 2) { memcpy (pdest,psource,(parsed_length-2)); dest->nFilledLen += (parsed_length-2); } break; case A1: if (parsed_length > 1) { memcpy (pdest,psource,(parsed_length-1)); dest->nFilledLen += (parsed_length-1); } break; case A0: memcpy (pdest,psource,(parsed_length)); dest->nFilledLen += (parsed_length); break; } if (source->nFilledLen < parsed_length) { printf ("\n FATAL Error"); return -1; } source->nFilledLen -= parsed_length; source->nOffset += parsed_length; return 1; }