void ASFFileProbeInfo::FileParse() { uint64_t offset = 0; uint64_t size = mFileDataReader->getFileSize(); while (size >= OBJECT_HEAD_LEN) { uint8_t buffer[OBJECT_HEAD_LEN]; mFileDataReader->readAt(offset, buffer, sizeof(buffer)); uint64_t objsize = U64LE_AT(buffer + OBJECT_ID_LEN); // printf("%x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]); if (!AsfGuidCmp(buffer, ASF_Header_Object)) { parseHeaderObject(offset + OBJECT_HEAD_LEN, size - OBJECT_HEAD_LEN); } else if (!AsfGuidCmp(buffer, ASF_Data_Object)) { parseDataObject(offset + OBJECT_HEAD_LEN, size - OBJECT_HEAD_LEN); } else if (!AsfGuidCmp(buffer, ASF_Simple_Index_Object)) { parseSimpleIndexObject(offset + OBJECT_HEAD_LEN, size - OBJECT_HEAD_LEN); } offset += objsize; size -= objsize; } printf("Parse ASF file\n"); }
ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) { uint8_t header[27]; ssize_t n; if ((n = mSource->readAt(offset, header, sizeof(header))) < (ssize_t)sizeof(header)) { if (n < 0) { return n; } else if (n == 0) { return ERROR_END_OF_STREAM; } else { return ERROR_IO; } } if (memcmp(header, "OggS", 4)) { return ERROR_MALFORMED; } if (header[4] != 0) { // Wrong version. return ERROR_UNSUPPORTED; } page->mFlags = header[5]; if (page->mFlags & ~7) { // Only bits 0-2 are defined in version 0. return ERROR_MALFORMED; } page->mGranulePosition = U64LE_AT(&header[6]); page->mSerialNo = U32LE_AT(&header[14]); page->mPageNo = U32LE_AT(&header[18]); page->mNumSegments = header[26]; if (mSource->readAt( offset + sizeof(header), page->mLace, page->mNumSegments) < (ssize_t)page->mNumSegments) { return ERROR_IO; } size_t totalSize = 0;; for (size_t i = 0; i < page->mNumSegments; ++i) { totalSize += page->mLace[i]; } return sizeof(header) + page->mNumSegments + totalSize; }
void ASFFileProbeInfo::parseHeaderObject(uint64_t offset, uint64_t size) { uint64_t pos = 0; uint32_t objectnum; mFileDataReader->readAt(offset + pos, &objectnum, sizeof(objectnum)); printf("object number :%d\n", objectnum); pos += 6; for (uint32_t i = 0; i < objectnum; i++) { uint8_t buffer[OBJECT_HEAD_LEN]; mFileDataReader->readAt(offset + pos, buffer, sizeof(buffer)); uint64_t objsize = U64LE_AT(buffer + OBJECT_ID_LEN); printf("%x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]); pos += objsize; } }
ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) { uint8_t header[27]; ssize_t n; if ((n = mSource->readAt(offset, header, sizeof(header))) < (ssize_t)sizeof(header)) { LOGV("failed to read %d bytes at offset 0x%016llx, got %ld bytes", sizeof(header), offset, n); if (n < 0) { return n; } else if (n == 0) { return ERROR_END_OF_STREAM; } else { return ERROR_IO; } } if (memcmp(header, "OggS", 4)) { return ERROR_MALFORMED; } if (header[4] != 0) { // Wrong version. return ERROR_UNSUPPORTED; } page->mFlags = header[5]; if (page->mFlags & ~7) { // Only bits 0-2 are defined in version 0. return ERROR_MALFORMED; } page->mGranulePosition = U64LE_AT(&header[6]); #if 0 printf("granulePosition = %llu (0x%llx)\n", page->mGranulePosition, page->mGranulePosition); #endif page->mSerialNo = U32LE_AT(&header[14]); page->mPageNo = U32LE_AT(&header[18]); page->mNumSegments = header[26]; if (mSource->readAt( offset + sizeof(header), page->mLace, page->mNumSegments) < (ssize_t)page->mNumSegments) { return ERROR_IO; } size_t totalSize = 0;; for (size_t i = 0; i < page->mNumSegments; ++i) { totalSize += page->mLace[i]; } #if 0 String8 tmp; for (size_t i = 0; i < page->mNumSegments; ++i) { char x[32]; sprintf(x, "%s%u", i > 0 ? ", " : "", (unsigned)page->mLace[i]); tmp.append(x); } LOGV("%c %s", page->mFlags & 1 ? '+' : ' ', tmp.string()); #endif return sizeof(header) + page->mNumSegments + totalSize; }
status_t OggWriter::threadFunc() { mEstimatedDurationUs = 0; mEstimatedSizeBytes = 0; bool stoppedPrematurely = true; int64_t previousPausedDurationUs = 0; int64_t maxTimestampUs = 0; status_t err = OK; int64_t ltotalSize = 0; int64_t timestampUs = 0; // int64_t tsUsPauseBeg = 0; int64_t tsUsPauseEnd = 0; //paused sample count int64_t smpPaused = 0; // prctl(PR_SET_NAME, (unsigned long)"OggWriter", 0, 0, 0); //struct sched_param param; //param.sched_priority = RTPM_PRIO_OMX_AUDIO; //sched_setscheduler(0, SCHED_RR, ¶m); //androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); //while (!mDone) { while (1 == 1) { MediaBuffer *buffer = NULL; MediaBuffer *buffer1 = NULL; if (mDone) { buffer = new MediaBuffer(0); buffer1 = buffer; } LOGV("OggWriter::threadFunc:mSource->read+:buffer=%p,buffer1=%p", buffer, buffer1); err = mSource->read(&buffer); LOGV("OggWriter::threadFunc:mSource->read-,err=%d,buffer=%p", err, buffer); if (err != OK) { break; } LOGV("OggWriter::threadFunc:buffer->range_length()=%d", buffer->range_length()); //buffer->range_length() == 0, ogg encoder SWIP caching data if (mPaused || buffer->range_length() == 0) { //mtk80721 deal pause time error+ if (mPaused && mPausedflag) { buffer->meta_data()->findInt64(kKeyTime, &tsUsPauseBeg); LOGD("OggWriter::threadFunc,pausetime=%d,tsUsPauseBeg=%lld", iPausedTime, tsUsPauseBeg); mPausedflag = false; } //- if (buffer->range_length() > 0) { //not vorbis header data should be released if (memcmp(buffer->data() + 29, "vorbis", 6) != 0) { buffer->release(); buffer = NULL; continue; } else { LOGD("ogg header:buffer=%p,size=%d", buffer, buffer->range_length()); } } else { buffer->release(); buffer = NULL; continue; } } mEstimatedSizeBytes += buffer->range_length(); if (exceedsFileSizeLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); break; } CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); if (timestampUs > 0) { if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } if (mResumed) { //mtk80721 deal pause time error+ buffer->meta_data()->findInt64(kKeyTime, &tsUsPauseEnd); LOGD("previousPausedDurationUs =%lld,pausetime=%d,tsUsPauseBeg=%lld,tsUsPauseEnd=%lld", previousPausedDurationUs, iPausedTime, tsUsPauseBeg, tsUsPauseEnd); previousPausedDurationUs = previousPausedDurationUs + (tsUsPauseEnd - tsUsPauseBeg); smpPaused = previousPausedDurationUs * mSampleRate / 1000000ll; LOGD("previousPausedDurationUs =%lld,samplecount=%lld", previousPausedDurationUs, smpPaused); //previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); //- mResumed = false; } timestampUs -= previousPausedDurationUs; LOGV("time stamp: %lld, previous paused duration: %lld", timestampUs, previousPausedDurationUs); if (timestampUs > maxTimestampUs) { maxTimestampUs = timestampUs; } } if (exceedsFileDurationLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); break; } LOGV("OggWriter::threadFunc:fwrite"); //write timestamp uint8_t *ptimestamp = (uint8_t *)buffer->data() + buffer->range_offset() + 6; uint64_t ts = U64LE_AT(ptimestamp); if (smpPaused > 0) { ts -= smpPaused; memcpy(ptimestamp, &ts, sizeof(int64_t)); } ssize_t n = fwrite( (const uint8_t *)buffer->data() + buffer->range_offset(), 1, buffer->range_length(), mFile); ltotalSize += n; if (n < (ssize_t)buffer->range_length()) { buffer->release(); buffer = NULL; break; } // XXX: How to tell it is stopped prematurely? if (stoppedPrematurely) { stoppedPrematurely = false; } LOGV("OggWriter::threadFunc:buffer->release:buffer=%p", buffer); buffer->release(); buffer = NULL; } if (stoppedPrematurely) { notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR); } /* // int bitrate = ltotalSize / (timestampUs/1E6) * 8; LOGV("ltotalSize=%lld, timestampUs=%lld, bitrate=%d",ltotalSize, timestampUs, bitrate); //seek to the bitrate field fseek(mFile, 44, SEEK_SET); // max bitrate fwrite(&bitrate, 1, sizeof(int), mFile); // nominal bitrate fwrite(&bitrate, 1, sizeof(int), mFile); // min bitrate fwrite(&bitrate, 1, sizeof(int), mFile); */ fflush(mFile); fclose(mFile); mFile = NULL; mReachedEOS = true; if (err == ERROR_END_OF_STREAM) { return OK; } return err; }