static void SetupKeyFrame(CP_INSTANCE *cpi) { /* Make sure the "last frame" buffer contains the first frame data as well. */ memcpy ( cpi->yuv0ptr, cpi->yuv1ptr, cpi->pb.ReconYPlaneSize + 2 * cpi->pb.ReconUVPlaneSize ); /* Initialise the cpi->pb.display_fragments and other fragment structures for the first frame. */ memset( cpi->pb.display_fragments, 1, cpi->pb.UnitFragments ); memset( cpi->extra_fragments, 1, cpi->pb.UnitFragments ); /* Set up for a KEY FRAME */ SetFrameType( &cpi->pb,KEY_FRAME ); }
static void CompressFrame( CP_INSTANCE *cpi) { ogg_int32_t min_blocks_per_frame; ogg_uint32_t i; int DropFrame = 0; ogg_uint32_t ResidueBlocksAdded=0; ogg_uint32_t KFIndicator = 0; double QModStep; double QModifier = 1.0; /* Clear down the macro block level mode and MV arrays. */ for ( i = 0; i < cpi->pb.UnitFragments; i++ ) { cpi->pb.FragCodingMethod[i] = CODE_INTER_NO_MV; /* Default coding mode */ cpi->pb.FragMVect[i].x = 0; cpi->pb.FragMVect[i].y = 0; } /* Default to delta frames. */ SetFrameType( &cpi->pb, DELTA_FRAME ); /* Clear down the difference arrays for the current frame. */ memset( cpi->pb.display_fragments, 0, cpi->pb.UnitFragments ); memset( cpi->extra_fragments, 0, cpi->pb.UnitFragments ); /* Calculate the target bytes for this frame. */ cpi->ThisFrameTargetBytes = cpi->frame_target_rate; /* Correct target to try and compensate for any overall rate error that is developing */ /* Set the max allowed Q for this frame based upon carry over history. First set baseline worst Q for this frame */ cpi->Configuration.ActiveMaxQ = cpi->Configuration.MaxQ + 10; if ( cpi->Configuration.ActiveMaxQ >= Q_TABLE_SIZE ) cpi->Configuration.ActiveMaxQ = Q_TABLE_SIZE - 1; /* Make a further adjustment based upon the carry over and recent history.. cpi->Configuration.ActiveMaxQ reduced by 1 for each 1/2 seconds worth of -ve carry over up to a limit of 6. Also cpi->Configuration.ActiveMaxQ reduced if frame is a "DropFrameCandidate". Remember that if we are behind the bit target carry over is -ve. */ if ( cpi->CarryOver < 0 ) { if ( cpi->DropFrameCandidate ) { cpi->Configuration.ActiveMaxQ -= 4; } if ( cpi->CarryOver < -((ogg_int32_t)cpi->Configuration.TargetBandwidth*3) ) cpi->Configuration.ActiveMaxQ -= 6; else cpi->Configuration.ActiveMaxQ += (ogg_int32_t) ((cpi->CarryOver*2) / (ogg_int32_t)cpi->Configuration.TargetBandwidth); /* Check that we have not dropped quality too far */ if ( cpi->Configuration.ActiveMaxQ < cpi->Configuration.MaxQ ) cpi->Configuration.ActiveMaxQ = cpi->Configuration.MaxQ; } /* Calculate the Q Modifier step size required to cause a step down from full target bandwidth to 40% of target between max Q and best Q */ QModStep = 0.5 / (double)((Q_TABLE_SIZE - 1) - cpi->Configuration.ActiveMaxQ); /* Set up the cpi->QTargetModifier[] table. */ for ( i = 0; i < cpi->Configuration.ActiveMaxQ; i++ ) { cpi->QTargetModifier[i] = QModifier; } for ( i = cpi->Configuration.ActiveMaxQ; i < Q_TABLE_SIZE; i++ ) { cpi->QTargetModifier[i] = QModifier; QModifier -= QModStep; } /* if we are allowed to drop frames and are falling behind (eg more than x frames worth of bandwidth) */ if ( cpi->pb.info.dropframes_p && ( cpi->DropCount < cpi->MaxConsDroppedFrames) && ( cpi->CarryOver < -((ogg_int32_t)cpi->Configuration.TargetBandwidth)) && ( cpi->DropFrameCandidate) ) { /* (we didn't do this frame so we should have some left over for the next frame) */ cpi->CarryOver += cpi->frame_target_rate; DropFrame = 1; cpi->DropCount ++; /* Adjust DropFrameTriggerBytes to account for the saving achieved. */ cpi->DropFrameTriggerBytes = (cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1))/DF_CANDIDATE_WINDOW; /* Even if we drop a frame we should account for it when considering key frame seperation. */ cpi->LastKeyFrame++; } else if ( cpi->CarryOver < -((ogg_int32_t)cpi->Configuration.TargetBandwidth * 2) ) { /* Reduce frame bit target by 1.75% for each 1/10th of a seconds worth of -ve carry over down to a minimum of 65% of its un-modified value. */ cpi->ThisFrameTargetBytes = (ogg_uint32_t)(cpi->ThisFrameTargetBytes * 0.65); } else if ( cpi->CarryOver < 0 ) { /* Note that cpi->CarryOver is a -ve here hence 1.0 "+" ... */ cpi->ThisFrameTargetBytes = (ogg_uint32_t)(cpi->ThisFrameTargetBytes * (1.0 + ( ((cpi->CarryOver * 10)/ ((ogg_int32_t)cpi-> Configuration.TargetBandwidth)) * 0.0175) )); } if ( !DropFrame ) { /* pick all the macroblock modes and motion vectors */ ogg_uint32_t InterError; ogg_uint32_t IntraError; /* Set Baseline filter level. */ ConfigurePP( &cpi->pp, cpi->pb.info.noise_sensitivity); /* Score / analyses the fragments. */ cpi->MotionScore = YUVAnalyseFrame(&cpi->pp, &KFIndicator ); /* Get the baseline Q value */ RegulateQ( cpi, cpi->MotionScore ); /* Recode blocks if the error score in last frame was high. */ ResidueBlocksAdded = 0; for ( i = 0; i < cpi->pb.UnitFragments; i++ ){ if ( !cpi->pb.display_fragments[i] ){ if ( cpi->LastCodedErrorScore[i] >= ResidueErrorThresh[cpi->pb.FrameQIndex] ) { cpi->pb.display_fragments[i] = 1; /* Force block update */ cpi->extra_fragments[i] = 1; /* Insures up to date pixel data is used. */ ResidueBlocksAdded ++; } } } /* Adjust the motion score to allow for residue blocks added. These are assumed to have below average impact on bitrate (Hence ResidueBlockFactor). */ cpi->MotionScore = cpi->MotionScore + (ResidueBlocksAdded / ResidueBlockFactor[cpi->pb.FrameQIndex]); /* Estimate the min number of blocks at best Q */ min_blocks_per_frame = (ogg_int32_t)(cpi->ThisFrameTargetBytes / GetEstimatedBpb( cpi, VERY_BEST_Q )); if ( min_blocks_per_frame == 0 ) min_blocks_per_frame = 1; /* If we have less than this number then consider adding in some extra blocks */ if ( cpi->MotionScore < min_blocks_per_frame ) { min_blocks_per_frame = cpi->MotionScore + (ogg_int32_t)(((min_blocks_per_frame - cpi->MotionScore) * 4) / 3 ); UpRegulateDataStream( cpi, VERY_BEST_Q, min_blocks_per_frame ); }else{ /* Reset control variable for best quality final pass. */ cpi->FinalPassLastPos = 0; } /* Get the modified Q prediction taking into account extra blocks added. */ RegulateQ( cpi, cpi->MotionScore ); /* Unless we are already well ahead (4 seconds of data) of the projected bitrate */ if ( cpi->CarryOver < (ogg_int32_t)(cpi->Configuration.TargetBandwidth * 4) ){ /* Look at the predicted Q (pbi->FrameQIndex). Adjust the target bits for this frame based upon projected Q and re-calculate. The idea is that if the Q is better than a given (good enough) level then we will try and save some bits for use in more difficult segments. */ cpi->ThisFrameTargetBytes = (ogg_int32_t) (cpi->ThisFrameTargetBytes * cpi->QTargetModifier[cpi->pb.FrameQIndex]); /* Recalculate Q again */ RegulateQ( cpi, cpi->MotionScore ); } /* Select modes and motion vectors for each of the blocks : return an error score for inter and intra */ PickModes( cpi, cpi->pb.YSBRows, cpi->pb.YSBCols, cpi->pb.info.width, &InterError, &IntraError ); /* decide whether we really should have made this frame a key frame */ /* forcing out a keyframe if the max interval is up is done at a higher level */ if( cpi->pb.info.keyframe_auto_p){ if( ( 2* IntraError < 5 * InterError ) && ( KFIndicator >= (ogg_uint32_t) cpi->pb.info.keyframe_auto_threshold) && ( cpi->LastKeyFrame > cpi->pb.info.keyframe_mindistance) ){ CompressKeyFrame(cpi); /* Code a key frame */ return; } } /* Increment the frames since last key frame count */ cpi->LastKeyFrame++; /* Proceed with the frame update. */ UpdateFrame(cpi); cpi->DropCount = 0; if ( cpi->MotionScore > 0 ){ /* Note the Quantizer used for each block coded. */ for ( i = 0; i < cpi->pb.UnitFragments; i++ ){ if ( cpi->pb.display_fragments[i] ){ cpi->FragmentLastQ[i] = cpi->pb.ThisFrameQualityValue; } } } }else{ /* even if we 'drop' a frame, a placeholder must be written as we currently assume fixed frame rate timebase as Ogg mapping invariant */ UpdateFrame(cpi); } }
void CMP4Demux::GetFrameInfo() { if ( iGotFrame ) return; if ( !iInputQueue ) { // file-reading case: set frame type according to // queue fullness SetFrameType(); if ( iFrameType == EDataNone ) return; } TBool frameAvailable = EFalse; // check if parser has info & data for next frame available TInt error = iParser->GetNextFrameInformation((CMP4Parser::TFrameType&)iFrameType, iFrameLen, frameAvailable); if ( error != KErrNone ) { if ( error != CParser::EParserEndOfStream ) { iMonitor->Error(error); } #ifdef _DEBUG else DASSERT( iStreamEnd ); #endif return; } if ( iInputQueue ) { // Read data from input queue until we know the frame type and length // and have data for it available while ( !frameAvailable ) { // Get a new input block with data while ( !iInputBlock ) { if ( (iInputBlock = iInputQueue->ReadBlock()) == NULL ) return; // Return empty blocks immediately if ( iInputBlock->Length() == 0 ) { iInputQueue->ReturnBlock(iInputBlock); iInputBlock = 0; } } // give input block to parser error = iParser->WriteDataBlock(*iInputBlock); if ( error != KErrNone ) { iMonitor->Error(error); return; } // Return our current input block iInputQueue->ReturnBlock(iInputBlock); iInputBlock = 0; // check if parser has info & data for next frame available error = iParser->GetNextFrameInformation((CMP4Parser::TFrameType&)iFrameType, iFrameLen, frameAvailable); if ( error != KErrNone ) { iMonitor->Error(error); return; } } } else { while ( !frameAvailable ) { if ( iFrameType == EDataAudio ) { iAudioEnd = ETrue; iAudioChannel->iTargetQueue->WriteStreamEnd(); PRINT((_L("MP4Demux, audio ended\n") )); } else { iVideoEnd = ETrue; iVideoChannel->iTargetQueue->WriteStreamEnd(); PRINT((_L("MP4Demux, video ended\n") )); } if ( iVideoEnd && (iAudioChannel == 0 || iAudioEnd) ) { iStreamEnd = ETrue; return; } iFrameType = EDataNone; SetFrameType(); if ( iFrameType == EDataNone ) return; error = iParser->GetNextFrameInformation((CMP4Parser::TFrameType&)iFrameType, iFrameLen, frameAvailable); if ( error != KErrNone ) { iMonitor->Error(error); return; } } } // at least one frame available iGotFrame = ETrue; }
// We should call SetFrameType first then reset(). // If we call reset() first, the queue may still has some "garbage" frame // from another thread's |OnMediaDataAvailable| before |SetFrameType|. void ResetWithFrameType(uint32_t aFrameType) { SetFrameType(aFrameType); Reset(); }
// // Description: // Construct the ARP response packet to support ARP offload. // static void ConstructARPResponse( PADAPTER padapter, u8 *pframe, u32 *pLength, u8 *pIPAddress ) { struct rtw_ieee80211_hdr *pwlanhdr; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct security_priv *psecuritypriv = &padapter->securitypriv; static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06}; u16 *fctrl; u32 pktlen; u8 *pARPRspPkt = pframe; //for TKIP Cal MIC u8 *payload = pframe; u8 EncryptionHeadOverhead = 0; pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; fctrl = &pwlanhdr->frame_ctl; *(fctrl) = 0; //------------------------------------------------------------------------- // MAC Header. //------------------------------------------------------------------------- SetFrameType(fctrl, WIFI_DATA); //SetFrameSubType(fctrl, 0); SetToDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); SetSeqNum(pwlanhdr, 0); SetDuration(pwlanhdr, 0); //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); //SET_80211_HDR_TO_DS(pARPRspPkt, 1); //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_DURATION(pARPRspPkt, 0); //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); #ifdef CONFIG_WAPI_SUPPORT *pLength = sMacHdrLng; #else *pLength = 24; #endif //YJ,del,120503 #if 0 //------------------------------------------------------------------------- // Qos Header: leave space for it if necessary. //------------------------------------------------------------------------- if(pStaQos->CurrentQosMode > QOS_DISABLE) { SET_80211_HDR_QOS_EN(pARPRspPkt, 1); PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng); *pLength += sQoSCtlLng; } #endif //------------------------------------------------------------------------- // Security Header: leave space for it if necessary. //------------------------------------------------------------------------- switch (psecuritypriv->dot11PrivacyAlgrthm) { case _WEP40_: case _WEP104_: EncryptionHeadOverhead = 4; break; case _TKIP_: EncryptionHeadOverhead = 8; break; case _AES_: EncryptionHeadOverhead = 8; break; #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: EncryptionHeadOverhead = 18; break; #endif default: EncryptionHeadOverhead = 0; } if(EncryptionHeadOverhead > 0) { _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead); *pLength += EncryptionHeadOverhead; //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW. SetPrivacy(fctrl); } //------------------------------------------------------------------------- // Frame Body. //------------------------------------------------------------------------- pARPRspPkt = (u8*)(pframe+ *pLength); // LLC header _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8); *pLength += 8; // ARP element pARPRspPkt += 8; SET_ARP_PKT_HW(pARPRspPkt, 0x0100); SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6); SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4); SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv))); SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress); #ifdef CONFIG_ARP_KEEP_ALIVE if (rtw_gw_addr_query(padapter)==0) { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip); } else #endif { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network))); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress); DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress)); } *pLength += 28; if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { u8 mic[8]; struct mic_data micdata; struct sta_info *psta = NULL; u8 priority[4]={0x0,0x0,0x0,0x0}; u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; DBG_871X("%s(): Add MIC\n",__FUNCTION__); psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network))); if (psta != NULL) { if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){ DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__); } //start to calculate the mic code rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]); } rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA priority[0]=0; rtw_secmicappend(&micdata, &priority[0], 4); rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28 rtw_secgetmic(&micdata,&(mic[0])); pARPRspPkt += 28; _rtw_memcpy(pARPRspPkt, &(mic[0]),8); *pLength += 8; } }