Ejemplo n.º 1
0
void TParser::ParseFOR(void)
{
    TType *pControlType;  // ptr to the control id's type object

    //--Append a placeholder for the location of the token that
    //--follows the FOR statement.  Remember the location of this
    //--placeholder.
    int atFollowLocationMarker = PutLocationMarker();

    //--<id>
    GetTokenAppend();
    if (token == tcIdentifier) {

	//--Verify the definition and type of the control id.
	TSymtabNode *pControlId = Find(pToken->String());
	if (pControlId->defn.how != dcUndefined) {
	    pControlType = pControlId->pType->Base();
	}
	else {
	    pControlId->defn.how = dcVariable;
	    pControlType = pControlId->pType = pIntegerType;
	}
	if (   (pControlType != pIntegerType)
	    && (pControlType != pCharType)
	    && (pControlType->form != fcEnum)) {
	    Error(errIncompatibleTypes);
	    pControlType = pIntegerType;
	}

	icode.Put(pControlId);
	GetTokenAppend();
    }
    else Error(errMissingIdentifier);

    //-- :=
    Resync(tlColonEqual, tlExpressionStart);
    CondGetTokenAppend(tcColonEqual, errMissingColonEqual);

    //--<expr-1>
    CheckAssignmentTypeCompatible(pControlType, ParseExpression(),
				  errIncompatibleTypes);

    //--TO or DOWNTO
    Resync(tlTODOWNTO, tlExpressionStart);
    if (TokenIn(token, tlTODOWNTO)) GetTokenAppend();
    else Error(errMissingTOorDOWNTO);

    //--<expr-2>
    CheckAssignmentTypeCompatible(pControlType, ParseExpression(),
				  errIncompatibleTypes);

    //--DO
    Resync(tlDO, tlStatementStart);
    CondGetTokenAppend(tcDO, errMissingDO);

    //--<stmt>
    ParseStatement();
    FixupLocationMarker(atFollowLocationMarker);
}
Ejemplo n.º 2
0
void TParser::ParseIF(void)
{
    //--Append a placeholder location marker for where to go to if
    //--<expr> is false.  Remember the location of this placeholder
    //--so it can be fixed up below.
    int atFalseLocationMarker = PutLocationMarker();

    //--<expr> : must be boolean
    GetTokenAppend();
    CheckBoolean(ParseExpression());

    //--THEN
    Resync(tlTHEN, tlStatementStart);
    CondGetTokenAppend(tcTHEN, errMissingTHEN);

    //--<stmt-1>
    ParseStatement();
    FixupLocationMarker(atFalseLocationMarker);

    if (token == tcELSE) {

	//--Append a placeholder location marker for the token that
	//--follows the IF statement.  Remember the location of this
	//--placeholder so it can be fixed up below.
	int atFollowLocationMarker = PutLocationMarker();

	//--ELSE <stmt-2>
	GetTokenAppend();
	ParseStatement();
	FixupLocationMarker(atFollowLocationMarker);
    }
}
/**
Refresh component instance names in Creo (Creo Refresh).

Pre-conditions:
 * MetaLink is running and CyPhy and CAD-assembler are connected
 * Creo is opened in assembly design editing mode.
   - CyPhy switches Creo to assembly design editing mode.
   - CyPhy starts CAD-assembler in assembly design editing mode.
 * There is an assembly design loaded in Creo.
Action:
 * Press the component name “Refresh” button.
Post-condition:
 * The names are displayed in the tree browser to the right side of the components.
*/
ProError DoResync()
{
	ProMdl mainMdl;
	ProMdlCurrentGet(&mainMdl);
	Resync(mainMdl);
	return PRO_TK_NO_ERROR;
}
Ejemplo n.º 4
0
 BOOL StartGraph(void)
 {
     SetupAllocator();
     if (m_pMC) m_pMC->Run();
     else m_pFilter->Run(0);
     Resync(0); // NewSegment + discontinuity /* e.g. ffdshow will not init byte count */
     return TRUE;
 }
Ejemplo n.º 5
0
		Result Tracker::TryResync(Result lastResult,bool excludeFrame) const
		{
			NST_VERIFY( NES_SUCCEEDED(lastResult) );

			if (NES_SUCCEEDED(lastResult) && lastResult != RESULT_NOP)
				Resync( excludeFrame );

			return lastResult;
		}
Ejemplo n.º 6
0
void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
{
	if (m_state < State_KeySet)
		throw BadState(AlgorithmName(), "Resynchronize", "key is set");

	m_bufferedDataLength = 0;
	m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
	m_state = State_KeySet;

	Resync(iv, this->ThrowIfInvalidIVLength(length));
	m_state = State_IVSet;
}
Ejemplo n.º 7
0
//************************************************************************************************
// 	cMenu::PowerButtonMenu()
//************************************************************************************************
bool cMenu::PowerButtonMenu(int rc_fd, fbvnc_event_t *ev)
{
   while (1)
   {
      cMenu Menu("VDR-Viewer Menü");
      Menu.Add(new cMenuSelItem("VDR-Viewer schließen", eMVViewerClose));
      Menu.Add(new cMenuSelItem("VDR ausschalten", eMVVdrShutdown));
      Menu.Add(new cMenuSeparatorItem());
      Menu.Add(new cMenuSelItem("Stream synchronisieren", eMVResync));
      Menu.Add(new cMenuSelItem("LCD umschalten", eMVToggleLCD));
      //Menu.Add(new cMenuSeparatorItem());
      //Menu.Add(new cMenuSelItem("Einstellungen", eMVSettings));
      EMenuValue RetVal = Menu.Show(rc_fd);
      
      dprintf("[vncv] MenuRet: %d\n", RetVal);
      switch(RetVal)
      {
      case eMVViewerClose: // Close VDR-Viewer
         ev->evtype = FBVNC_EVENT_QUIT;
         return false;
         break;
         
      case eMVVdrShutdown: // Send Key to VDR
         ev->evtype = FBVNC_EVENT_NULL;
         return false;
         break;
         
      case eMVResync: // Resync Stream
         Resync();
         ev->evtype = FBVNC_EVENT_NULL;
         return true;
         break;
         
      case eMVToggleLCD: // Toggle LCD
         ToggleLCD();
         ev->evtype = FBVNC_EVENT_NULL;
         return true;
         break;
         
      case eMVSettings: // Show Settings Menu
         SettingsMenu(rc_fd);
         break;
         
      default:
         ev->evtype = FBVNC_EVENT_NULL;
         return true;
         break;
      }
   }
   
   ev->evtype = FBVNC_EVENT_NULL;
   return false;
}
Ejemplo n.º 8
0
bool SniffMP3(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
    off_t pos = 0;
    uint32_t header;
    if (!Resync(source, 0, &pos, &header)) {
        return false;
    }

    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
    *confidence = 0.3f;

    return true;
}
Ejemplo n.º 9
0
void TParser::ParseAssignment(const TSymtabNode *pTargetId)
{
    TType *pTargetType = ParseVariable(pTargetId);

    //-- :=
    Resync(tlColonEqual, tlExpressionStart);
    CondGetTokenAppend(tcColonEqual, errMissingColonEqual);

    //--<expr>
    TType *pExprType = ParseExpression();

    //--Check for assignment compatibility.
    CheckAssignmentTypeCompatible(pTargetType, pExprType,
				  errIncompatibleAssignment);
}
Ejemplo n.º 10
0
void TParser::ParseStatement(void)
{
    InsertLineMarker();

    //--Call the appropriate parsing function based on
    //--the statement's first token.
    switch (token) {

	case tcIdentifier: {

	    //--Search for the identifier and enter it if
	    //--necessary.  Append the symbol table node handle
	    //--to the icode.
	    TSymtabNode *pNode = Find(pToken->String());
	    icode.Put(pNode);

	    //--Based on how the identifier is defined,
	    //--parse an assignment statement or a procedure call.
	    if (pNode->defn.how == dcUndefined) {
		pNode->defn.how = dcVariable;
		SetType(pNode->pType, pDummyType);
		ParseAssignment(pNode);
	    }
	    else if (pNode->defn.how == dcProcedure) {
		ParseSubroutineCall(pNode, true);
	    }
	    else ParseAssignment(pNode);

	    break;
	}

	case tcREPEAT:      ParseREPEAT();      break;
	case tcWHILE:       ParseWHILE();       break;
	case tcIF:          ParseIF();          break;
	case tcFOR:         ParseFOR();         break;
	case tcCASE:        ParseCASE();        break;
	case tcBEGIN:       ParseCompound();    break;
    }

    //--Resynchronize at a proper statement ending.
    if (token != tcEndOfFile) {
	Resync(tlStatementFollow, tlStatementStart);
    }
}
Ejemplo n.º 11
0
void TParser::ParseWHILE(void)
{
    //--Append a placeholder location marker for the token that
    //--follows the WHILE statement.  Remember the location of this
    //--placeholder so it can be fixed up below.
    int atFollowLocationMarker = PutLocationMarker();

    //--<expr> : must be boolean
    GetTokenAppend();
    CheckBoolean(ParseExpression());

    //--DO
    Resync(tlDO, tlStatementStart);
    CondGetTokenAppend(tcDO, errMissingDO);

    //--<stmt>
    ParseStatement();
    FixupLocationMarker(atFollowLocationMarker);
}
Ejemplo n.º 12
0
bool SniffMP3(
        const sp<DataSource> &source, String8 *mimeType,
        float *confidence, sp<AMessage> *meta) {
    off64_t pos = 0;
    off64_t post_id3_pos;
    uint32_t header;
    if (!Resync(source, 0, &pos, &post_id3_pos, &header)) {
        return false;
    }

    *meta = new AMessage;
    (*meta)->setInt64("offset", pos);
    (*meta)->setInt32("header", header);
    (*meta)->setInt64("post-id3-offset", post_id3_pos);

    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
    *confidence = 0.2f;

    return true;
}
Ejemplo n.º 13
0
void TParser::ParseCaseBranch(const TType *pExprType,
			      TCaseItem *&pCaseItemList)
{
    int caseLabelFlag;  // true if another CASE label, else false

    //--<case-label-list>
    do {
	ParseCaseLabel(pExprType, pCaseItemList);
	if (token == tcComma) {

	    //--Saw comma, look for another CASE label.
	    GetTokenAppend();
	    if (TokenIn(token, tlCaseLabelStart)) caseLabelFlag = true;
	    else {
		Error(errMissingConstant);
		caseLabelFlag = false;
	    }
	}
	else caseLabelFlag = false;

    } while (caseLabelFlag);

    //-- :
    Resync(tlColon, tlStatementStart);
    CondGetTokenAppend(tcColon, errMissingColon);

    //--Loop to set the branch statement location into each CASE item
    //--for this branch.
    for (TCaseItem *pItem = pCaseItemList;
	 pItem && (pItem->atBranchStmt == 0);
	 pItem = pItem->next) {
	pItem->atBranchStmt = icode.CurrentLocation() - 1;
    }

    //--<stmt>
    ParseStatement();
}
Ejemplo n.º 14
0
MP3Extractor::MP3Extractor(const sp<DataSource> &source)
    : mDataSource(source),
      mFirstFramePos(-1),
      mFixedHeader(0) {
    off_t pos = 0;
    uint32_t header;
    bool success = Resync(mDataSource, 0, &pos, &header);
    CHECK(success);

    if (success) {
        mFirstFramePos = pos;
        mFixedHeader = header;

        size_t frame_size;
        int sample_rate;
        int num_channels;
        int bitrate;
        get_mp3_frame_size(
                header, &frame_size, &sample_rate, &num_channels, &bitrate);

        mMeta = new MetaData;

        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
        mMeta->setInt32(kKeySampleRate, sample_rate);
        mMeta->setInt32(kKeyBitRate, bitrate);
        mMeta->setInt32(kKeyChannelCount, num_channels);

        off_t fileSize;
        if (mDataSource->getSize(&fileSize) == OK) {
            mMeta->setInt32(
                    kKeyDuration,
                    8 * (fileSize - mFirstFramePos) / bitrate);
            mMeta->setInt32(kKeyTimeScale, 1000);
        }
    }
}
Ejemplo n.º 15
0
status_t MP3Source::getNextFramePos(off_t *curPos, off_t *pNextPos,int64_t * frameTsUs)
{
	
	uint8_t mp3header[4];
	size_t frame_size;
	int samplerate=0;
	int num_sample =0;
	for(;;)
	{
		ssize_t n = mDataSource->readAt(*curPos, mp3header, 4);
		if (n < 4) {
			MP3_EXTR_DBG("For Seek Talbe :ERROR_END_OF_STREAM");
			return ERROR_END_OF_STREAM;
		}
       // MP3_EXTR_DBG("mp3header[0]=%0x,mp3header[1]=%0x,mp3header[2]=%0x,mp3header[3]=%0x",mp3header[0],mp3header[1],mp3header[2],mp3header[3]); 
        uint32_t header = U32_AT((const uint8_t *)mp3header);      
        if ((header & kMask) == (mFixedHeader & kMask)
            && GetMPEGAudioFrameSize(header, &frame_size,
								&samplerate, NULL,NULL,&num_sample)) 
		{            	  
            break; 
        }
        // Lost sync.
        //MP3_EXTR_DBG("getNextFramePos::lost sync! header = 0x%08x, old header = 0x%08x\n", header, mFixedHeader);
        off64_t pos = *curPos;
        if (!Resync(mDataSource, mFixedHeader, &pos, NULL,NULL)) {
             //MP3_EXTR_DBG("getNextFramePos---Unable to resync. Signalling end of stream.");          
             return ERROR_END_OF_STREAM;
        }
        *curPos = pos;       
        // Try again with the new position.
     }
     *pNextPos=*curPos+frame_size;
	 *frameTsUs = 1000000ll * num_sample/samplerate;
   return OK;
}
Ejemplo n.º 16
0
status_t MP3Source::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    bool seekCBR = false;

    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
        int64_t actualSeekTimeUs = seekTimeUs;
#ifndef ANDROID_DEFAULT_CODE
		if(!mEnableTOC){
#endif
        if (mSeeker == NULL
                || !mSeeker->getOffsetForTime(&actualSeekTimeUs, &mCurrentPos)) {
            int32_t bitrate;
            if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
                // bitrate is in bits/sec.
                ALOGI("no bitrate");

                return ERROR_UNSUPPORTED;
            }

            mCurrentTimeUs = seekTimeUs;
            mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
            seekCBR = true;
        } else {
            mCurrentTimeUs = actualSeekTimeUs;
        }
#ifndef ANDROID_DEFAULT_CODE
		}else{
			MP3_EXTR_DBG("before getFramePos seekTimeUs=%lld",seekTimeUs);
			off_t ActualPos=0;
			status_t stat=getFramePos(seekTimeUs, &mCurrentTimeUs, &ActualPos, true);		 
			if(stat==BAD_VALUE){
				int32_t bitrate;
	            if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
	                // bitrate is in bits/sec.
	                MP3_EXTR_WARN("no bitrate");
	                return ERROR_UNSUPPORTED;
	            }
				mCurrentTimeUs = seekTimeUs;
				mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
				if (mSeeker == NULL || !mSeeker->getOffsetForTime(&actualSeekTimeUs, &mCurrentPos)) {
            		int32_t bitrate;
            		if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
              		  // bitrate is in bits/sec.
                		ALOGI("no bitrate");

             		   return ERROR_UNSUPPORTED;
           			 }

            		mCurrentTimeUs = seekTimeUs;
            		mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
            		seekCBR = true;
        		} else {
            		mCurrentTimeUs = actualSeekTimeUs;
       			}
			}else if(stat == ERROR_END_OF_STREAM){
				return stat;
			}else{
				mCurrentPos= ActualPos;
				MP3_EXTR_DBG("after seek mCurrentTimeUs=%lld,pActualPos=%ld",mCurrentTimeUs,ActualPos);
			}


		}
#endif
        mBasisTimeUs = mCurrentTimeUs;
        mSamplesRead = 0;
    }

    MediaBuffer *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);
    if (err != OK) {
        return err;
    }

    size_t frame_size;
    int bitrate;
    int num_samples;
    int sample_rate;
    for (;;) {
        ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
        if (n < 4) {
            buffer->release();
            buffer = NULL;

            return ERROR_END_OF_STREAM;
        }

        uint32_t header = U32_AT((const uint8_t *)buffer->data());

        if ((header & kMask) == (mFixedHeader & kMask)
            && GetMPEGAudioFrameSize(
                header, &frame_size, &sample_rate, NULL,
                &bitrate, &num_samples)) {

            // re-calculate mCurrentTimeUs because we might have called Resync()
            if (seekCBR) {
                mCurrentTimeUs = (mCurrentPos - mFirstFramePos) * 8000 / bitrate;
                mBasisTimeUs = mCurrentTimeUs;
            }

            break;
        }

        // Lost sync.
        ALOGV("lost sync! header = 0x%08x, old header = 0x%08x\n", header, mFixedHeader);

        off64_t pos = mCurrentPos;
        if (!Resync(mDataSource, mFixedHeader, &pos, NULL, NULL)) {
            ALOGE("Unable to resync. Signalling end of stream.");

            buffer->release();
            buffer = NULL;

            return ERROR_END_OF_STREAM;
        }

        mCurrentPos = pos;

        // Try again with the new position.
    }

    CHECK(frame_size <= buffer->size());

    ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), frame_size);
    if (n < (ssize_t)frame_size) {
        buffer->release();
        buffer = NULL;

        return ERROR_END_OF_STREAM;
    }

    buffer->set_range(0, frame_size);

    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);

    mCurrentPos += frame_size;

    mSamplesRead += num_samples;
    mCurrentTimeUs = mBasisTimeUs + ((mSamplesRead * 1000000) / sample_rate);

    *out = buffer;

    return OK;
}
MP3Extractor::MP3Extractor(
        const sp<DataSource> &source, const sp<AMessage> &meta)
    : mInitCheck(NO_INIT),
      mDataSource(source),
      mFirstFramePos(-1),
      mFixedHeader(0) {
    off64_t pos = 0;
    off64_t post_id3_pos;
    uint32_t header;
    bool success;

    int64_t meta_offset;
    uint32_t meta_header;
    int64_t meta_post_id3_offset;
    if (meta != NULL
            && meta->findInt64("offset", &meta_offset)
            && meta->findInt32("header", (int32_t *)&meta_header)
            && meta->findInt64("post-id3-offset", &meta_post_id3_offset)) {
        // The sniffer has already done all the hard work for us, simply
        // accept its judgement.
        pos = (off64_t)meta_offset;
        header = meta_header;
        post_id3_pos = (off64_t)meta_post_id3_offset;

        success = true;
    } else {
        success = Resync(mDataSource, 0, &pos, &post_id3_pos, &header);
    }

    if (!success) {
        // mInitCheck will remain NO_INIT
        return;
    }

    mFirstFramePos = pos;
    mFixedHeader = header;

    size_t frame_size;
    int sample_rate;
    int num_channels;
    int bitrate;
    GetMPEGAudioFrameSize(
            header, &frame_size, &sample_rate, &num_channels, &bitrate);

    mMeta = new MetaData;

    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
    mMeta->setInt32(kKeySampleRate, sample_rate);
    mMeta->setInt32(kKeyBitRate, bitrate * 1000);
    mMeta->setInt32(kKeyChannelCount, num_channels);

    mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);

    if (mSeeker == NULL) {
        mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
    }

    int64_t durationUs;

    if (mSeeker == NULL || !mSeeker->getDuration(&durationUs)) {
        off64_t fileSize;
        if (mDataSource->getSize(&fileSize) == OK) {
            durationUs = 8000LL * (fileSize - mFirstFramePos) / bitrate;
        } else {
            durationUs = -1;
        }
    }

    if (durationUs >= 0) {
        mMeta->setInt64(kKeyDuration, durationUs);
    }

    mInitCheck = OK;
}
Ejemplo n.º 18
0
CryptModeCBC::CryptModeCBC(BlockCipher* cipher, bool encrypt, const unsigned char* iv):CryptMode(cipher, encrypt)
{
    if(encrypt)block_transformer=cipher->CreateEncryptor();
    else block_transformer=cipher->CreateDecryptor();
    Resync(iv);
}
Ejemplo n.º 19
0
void TParser::ParseCASE(void)
{
    TCaseItem *pCaseItemList;   // ptr to list of CASE items
    int        caseBranchFlag;  // true if another CASE branch,
				//   else false

    pCaseItemList = NULL;

    //--Append placeholders for the location of the token that
    //--follows the CASE statement and of the CASE branch table.
    //--Remember the locations of these placeholders.
    int atFollowLocationMarker      = PutLocationMarker();
    int atBranchTableLocationMarker = PutLocationMarker();

    //--<expr>
    GetTokenAppend();
    TType *pExprType = ParseExpression()->Base();

    //--Verify the type of the CASE expression.
    if (   (pExprType != pIntegerType)
	&& (pExprType != pCharType)
	&& (pExprType->form != fcEnum)) {
	Error(errIncompatibleTypes);
    }

    //--OF
    Resync(tlOF, tlCaseLabelStart);
    CondGetTokenAppend(tcOF, errMissingOF);

    //--Loop to parse CASE branches.
    caseBranchFlag = TokenIn(token, tlCaseLabelStart);
    while (caseBranchFlag) {
	if (TokenIn(token, tlCaseLabelStart)) {
	    ParseCaseBranch(pExprType, pCaseItemList);
	}

	if (token == tcSemicolon) {
	    GetTokenAppend();
	    caseBranchFlag = true;
	}
	else if (TokenIn(token, tlCaseLabelStart)) {
	    Error(errMissingSemicolon);
	    caseBranchFlag = true;
	}
	else caseBranchFlag = false;
    }

    //--Append the branch table to the intermediate code.
    FixupLocationMarker(atBranchTableLocationMarker);
    TCaseItem *pItem = pCaseItemList;
    TCaseItem *pNext;
    do {
	PutCaseItem(pItem->labelValue, pItem->atBranchStmt);
	pNext = pItem->next;
	delete pItem;
	pItem = pNext;
    } while (pItem);
    PutCaseItem(0, 0);  // end of table

    //--END
    Resync(tlEND, tlStatementStart);
    CondGetTokenAppend(tcEND, errMissingEND);
    FixupLocationMarker(atFollowLocationMarker);
}
Ejemplo n.º 20
0
status_t MP3Source::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    if (options != NULL && options->getSeekTo(&seekTimeUs)) {
        int32_t bitrate;
        if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
            // bitrate is in kbits/sec.
            LOGI("no bitrate");

            return ERROR_UNSUPPORTED;
        }

        mCurrentTimeUs = seekTimeUs;
        mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 1000000 * 125;
    }

    MediaBuffer *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);
    if (err != OK) {
        return err;
    }

    size_t frame_size;
    for (;;) {
        ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), 4);
        if (n < 4) {
            buffer->release();
            buffer = NULL;

            return ERROR_END_OF_STREAM;
        }

        uint32_t header = U32_AT((const uint8_t *)buffer->data());
        
        if (get_mp3_frame_size(header, &frame_size)) {
            break;
        }

        // Lost sync.
        LOGW("lost sync!\n");

        off_t pos = mCurrentPos;
        if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) {
            LOGE("Unable to resync. Signalling end of stream.");

            buffer->release();
            buffer = NULL;

            return ERROR_END_OF_STREAM;
        }

        mCurrentPos = pos;

        // Try again with the new position.
    }

    CHECK(frame_size <= buffer->size());

    ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), frame_size);
    if (n < (ssize_t)frame_size) {
        buffer->release();
        buffer = NULL;

        return ERROR_END_OF_STREAM;
    }

    buffer->set_range(0, frame_size);

    buffer->meta_data()->setInt32(kKeyTimeUnits, mCurrentTimeUs / 1000);
    buffer->meta_data()->setInt32(kKeyTimeScale, 1000);

    mCurrentPos += frame_size;
    mCurrentTimeUs += 1152 * 1000000 / 44100;

    *out = buffer;

    return OK;
}