Exemple #1
0
AMRExtractor::AMRExtractor(const sp<DataSource> &source)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mOffsetTableLength(0) {
    String8 mimeType;
    float confidence;
    if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) {
        return;
    }

    mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);

    mMeta = new MetaData;
    mMeta->setCString(
            kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
                                  : MEDIA_MIMETYPE_AUDIO_AMR_NB);

    mMeta->setInt32(kKeyChannelCount, 1);
    mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000);

    off64_t offset = mIsWide ? 9 : 6;
    off64_t streamSize;
    size_t frameSize, numFrames = 0;
    int64_t duration = 0;

    if (mDataSource->getSize(&streamSize) == OK) {
         while (offset < streamSize) {
             status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
             if (status == ERROR_END_OF_STREAM) {
                 break;
             } else if (status != OK) {
                return;
            }

            if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) {
                CHECK_EQ(mOffsetTableLength, numFrames / 50);
                mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6);
                mOffsetTableLength ++;
            }

            offset += frameSize;
            duration += 20000;  // Each frame is 20ms
            numFrames ++;
        }

        mMeta->setInt64(kKeyDuration, duration);
    }

    mInitCheck = OK;
}
Exemple #2
0
status_t AMRSource::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
        size_t size;
        int64_t seekFrame = seekTimeUs / 20000ll;  // 20ms per frame.
        mCurrentTimeUs = seekFrame * 20000ll;

        size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
        if (index >= mOffsetTableLength) {
            index = mOffsetTableLength - 1;
        }

        mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);

        for (size_t i = 0; i< seekFrame - index * 50; i++) {
            status_t err;
            if ((err = getFrameSizeByOffset(mDataSource, mOffset,
                            mIsWide, &size)) != OK) {
                return err;
            }
            mOffset += size;
        }
    }

    uint8_t header;
    ssize_t n = mDataSource->readAt(mOffset, &header, 1);

    if (n < 1) {
        return ERROR_END_OF_STREAM;
    }

    if (header & 0x83) {
        // Padding bits must be 0.

        ALOGE("padding bits must be 0, header is 0x%02x", header);

        return ERROR_MALFORMED;
    }

    unsigned FT = (header >> 3) & 0x0f;

    size_t frameSize = getFrameSize(mIsWide, FT);
    if (frameSize == 0) {
        return ERROR_MALFORMED;
    }

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

    n = mDataSource->readAt(mOffset, buffer->data(), frameSize);

    if (n != (ssize_t)frameSize) {
        buffer->release();
        buffer = NULL;

        if (n < 0) {
            return ERROR_IO;
        } else {
            // only partial frame is available, treat it as EOS.
            mOffset += n;
            return ERROR_END_OF_STREAM;
        }
    }

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

    mOffset += frameSize;
    mCurrentTimeUs += 20000;  // Each frame is 20ms

    *out = buffer;

    return OK;
}
status_t AMRSource::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
#ifdef MTK_AOSP_ENHANCEMENT

        // Maybe risk (int)index >= (uint)mOffsetTableLength warning: comparison between signed and unsigned integer expressions
        // should check seekTimeUs < 0 case
	if (seekTimeUs < 0) {
	    ALOGW("seekTimeUs:%lld < 0", seekTimeUs);
	    seekTimeUs = 0;
	}
#endif
        size_t size;
        int64_t seekFrame = seekTimeUs / 20000ll;  // 20ms per frame.
        mCurrentTimeUs = seekFrame * 20000ll;

        size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
        if (index >= mOffsetTableLength) {
            index = mOffsetTableLength - 1;
        }

        mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);

        for (size_t i = 0; i< seekFrame - index * 50; i++) {
            status_t err;
            if ((err = getFrameSizeByOffset(mDataSource, mOffset,
                            mIsWide, &size)) != OK) {
                return err;
            }
            mOffset += size;
        }
    }

    uint8_t header;
    ssize_t n = mDataSource->readAt(mOffset, &header, 1);

    if (n < 1) {
        return ERROR_END_OF_STREAM;
    }
#ifdef MTK_AOSP_ENHANCEMENT

    int count = 0;
	while(header & 0x83)
	{  
        if ((count % 10) == 0)
            SXLOGW("AMRSource::read--Frame head error,skip until to find an valid one count %d",count);
	    mOffset++;
	    count++;
	    if (count>320) {
	    	SXLOGW("getFrameSizeByOffset--can not find the correct frame header in 64 byte");
	        return ERROR_END_OF_STREAM;
	    }
		n = mDataSource->readAt(mOffset, &header, 1);
	    if (n < 1) {
            return ERROR_END_OF_STREAM;
		}
	}
#else
    if (header & 0x83) {
        // Padding bits must be 0.

        ALOGE("padding bits must be 0, header is 0x%02x", header);

        return ERROR_MALFORMED;
    }
#endif

    unsigned FT = (header >> 3) & 0x0f;

    size_t frameSize = getFrameSize(mIsWide, FT);
    if (frameSize == 0) {
        return ERROR_MALFORMED;
    }

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

    n = mDataSource->readAt(mOffset, buffer->data(), frameSize);

    if (n != (ssize_t)frameSize) {
        buffer->release();
        buffer = NULL;

        return ERROR_IO;
    }

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

    mOffset += frameSize;
    mCurrentTimeUs += 20000;  // Each frame is 20ms

    *out = buffer;

    return OK;
}
AMRExtractor::AMRExtractor(const sp<DataSource> &source)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mOffsetTableLength(0) {
    String8 mimeType;
    float confidence;
    if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) {
        return;
    }

    mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);

    mMeta = new MetaData;
    mMeta->setCString(
            kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
                                  : MEDIA_MIMETYPE_AUDIO_AMR_NB);

    mMeta->setInt32(kKeyChannelCount, 1);
    mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000);

    off64_t offset = mIsWide ? 9 : 6;
    off64_t streamSize;
    size_t frameSize, numFrames = 0;
    int64_t duration = 0;
#ifdef MTK_AOSP_ENHANCEMENT

    status_t ret = 0;
    bool streamingFlag = mDataSource->flags() & DataSource::kIsCachingDataSource;
    char *pData = new char [Buffer_Count_Readed];
    ssize_t dataLen = 0;
    size_t dataOffset = 0;
    SXLOGD("AMRExtractor--is streaming flag=%d, pData:0x%x", streamingFlag, pData);
#endif

    if (mDataSource->getSize(&streamSize) == OK) {
         while (offset < streamSize) {
#ifdef MTK_AOSP_ENHANCEMENT

            if (pData) {
                if (dataLen==0) {
                    dataLen = mDataSource->readAt(offset, (void *)pData, Buffer_Count_Readed);
		    if (dataLen < 0) {
                         return;
		    } 
                    dataOffset = 0;
                }
                ret = getFrameSizeByOffset_MMIO((uint8_t *)pData, dataLen, dataOffset, offset, mIsWide, &frameSize);
                if (ret==NO_MEMORY) {
                    dataLen = 0;
                    continue;
                }
            }else {
                ret = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
            }
            if (ret==ERROR_END_OF_STREAM) {
                break;
            }else if(ret!=OK) {
                if (pData) delete [] pData;
                pData = 0;
                SXLOGD("AMRExtractor--getFrameSizeByOffset is not ok!");
                return;
            }
#else
            if (getFrameSizeByOffset(source, offset, mIsWide, &frameSize) != OK) {
                return;
            }
#endif
            if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) {
                CHECK_EQ(mOffsetTableLength, numFrames / 50);
                mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6);
                mOffsetTableLength ++;
            }
#ifdef MTK_AOSP_ENHANCEMENT

            else if(streamingFlag&&(numFrames>=50*OFFSET_TABLE_LEN)) {
                duration += 20000*(streamSize - offset)/((offset - (mIsWide ? 9: 6))/(off64_t)numFrames);
                SXLOGV("AMRExtractor--end duration=%lld, frame size = %lld", duration, (offset - (mIsWide ? 9: 6))/(off64_t)numFrames);
                break;
            }
#endif
            offset += frameSize;
            duration += 20000;  // Each frame is 20ms
            numFrames ++;
        }

        mMeta->setInt64(kKeyDuration, duration);
    }
#ifdef MTK_AOSP_ENHANCEMENT

    if (pData) delete [] pData;
    pData = 0;
    SXLOGD("AMRExtractor--constructor out -");
#endif
    mInitCheck = OK;
}