/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "MPEG4Writer"
#include <arpa/inet.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utils/Log.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/Utils.h>
#include <media/mediarecorder.h>
#include <cutils/properties.h>
#include "include/ESDS.h"
#ifndef __predict_false
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
#endif
#define WARN_UNLESS(condition, message, ...) \
( (__predict_false(condition)) ? false : ({ \
ALOGW("Condition %s failed " message, #condition, ##__VA_ARGS__); \
true; \
}))
namespace android {
static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
// filesystem file size
// used by most SD cards
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
static const uint8_t kNalUnitTypePicParamSet = 0x08;
static const int64_t kInitialDelayTimeUs = 700000LL;
static const char kMetaKey_Version[] = "com.android.version";
#ifdef SHOW_MODEL_BUILD
static const char kMetaKey_Model[] = "com.android.model";
static const char kMetaKey_Build[] = "com.android.build";
#endif
static const char kMetaKey_CaptureFps[] = "com.android.capture.fps";
static const int64_t kMax32BitDuration = 0x007fffffffLL;
/* uncomment to include model and build in meta */
//#define SHOW_MODEL_BUILD 1
class MPEG4Writer::Track {
public:
Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
~Track();
status_t start(MetaData *params);
status_t stop();
status_t pause();
bool reachedEOS();
int64_t getDurationUs() const;
int64_t getEstimatedTrackSizeBytes() const;
void writeTrackHeader(bool use32BitOffset = true);
void bufferChunk(int64_t timestampUs);
bool isAvc() const { return mIsAvc; }
bool isAudio() const { return mIsAudio; }
//add by xuhui for subtitle
bool isSubtitle() const { return mIsSubtitle; }
bool isMPEG4() const { return mIsMPEG4; }
void addChunkOffset(off64_t offset);
int32_t getTrackId() const { return mTrackId; }
status_t dump(int fd, const Vector<String16>& args) const;
static const char *getFourCCForMime(const char *mime);
private:
enum {
kMaxCttsOffsetTimeUs = 1000000LL, // 1 second
kSampleArraySize = 1000,
};
// A helper class to handle faster write box with table entries
template<class TYPE>
struct ListTableEntries {
ListTableEntries(uint32_t elementCapacity, uint32_t entryCapacity)
: mElementCapacity(elementCapacity),
mEntryCapacity(entryCapacity),
mTotalNumTableEntries(0),
mNumValuesInCurrEntry(0),
mCurrTableEntriesElement(NULL) {
CHECK_GT(mElementCapacity, 0);
CHECK_GT(mEntryCapacity, 0);
// Ensure no integer overflow on allocation in add().
CHECK_LT(mEntryCapacity, UINT32_MAX / mElementCapacity);
}
// Free the allocated memory.
~ListTableEntries() {
while (!mTableEntryList.empty()) {
typename List<TYPE *>::iterator it = mTableEntryList.begin();
delete[] (*it);
mTableEntryList.erase(it);
}
}
// Replace the value at the given position by the given value.
// There must be an existing value at the given position.
// @arg value must be in network byte order
// @arg pos location the value must be in.
void set(const TYPE& value, uint32_t pos) {
CHECK_LT(pos, mTotalNumTableEntries * mEntryCapacity);
typename List<TYPE *>::iterator it = mTableEntryList.begin();
uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
while (it != mTableEntryList.end() && iterations > 0) {
++it;
--iterations;
}
CHECK(it != mTableEntryList.end());
CHECK_EQ(iterations, 0);
(*it)[(pos % (mElementCapacity * mEntryCapacity))] = value;
}
// Get the value at the given position by the given value.
// @arg value the retrieved value at the position in network byte order.
// @arg pos location the value must be in.
// @return true if a value is found.
bool get(TYPE& value, uint32_t pos) const {
if (pos >= mTotalNumTableEntries * mEntryCapacity) {
return false;
}
typename List<TYPE *>::iterator it = mTableEntryList.begin();
uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
while (it != mTableEntryList.end() && iterations > 0) {
++it;
--iterations;
}
CHECK(it != mTableEntryList.end());
CHECK_EQ(iterations, 0);
value = (*it)[(pos % (mElementCapacity * mEntryCapacity))];
return true;
}
// Store a single value.
// @arg value must be in network byte order.
void add(const TYPE& value) {
CHECK_LT(mNumValuesInCurrEntry, mElementCapacity);
uint32_t nEntries = mTotalNumTableEntries % mElementCapacity;
uint32_t nValues = mNumValuesInCurrEntry % mEntryCapacity;
if (nEntries == 0 && nValues == 0) {
mCurrTableEntriesElement = new TYPE[mEntryCapacity * mElementCapacity];
CHECK(mCurrTableEntriesElement != NULL);
mTableEntryList.push_back(mCurrTableEntriesElement);
}
uint32_t pos = nEntries * mEntryCapacity + nValues;
mCurrTableEntriesElement[pos] = value;
++mNumValuesInCurrEntry;
if ((mNumValuesInCurrEntry % mEntryCapacity) == 0) {
++mTotalNumTableEntries;
mNumValuesInCurrEntry = 0;
}
}
// Write out the table entries:
// 1. the number of entries goes first
// 2. followed by the values in the table enties in order
// @arg writer the writer to actual write to the storage
void write(MPEG4Writer *writer) const {
CHECK_EQ(mNumValuesInCurrEntry % mEntryCapacity, 0);
uint32_t nEntries = mTotalNumTableEntries;
writer->writeInt32(nEntries);
for (typename List<TYPE *>::iterator it = mTableEntryList.begin();
it != mTableEntryList.end(); ++it) {
CHECK_GT(nEntries, 0);
if (nEntries >= mElementCapacity) {
writer->write(*it, sizeof(TYPE) * mEntryCapacity, mElementCapacity);
nEntries -= mElementCapacity;
} else {
writer->write(*it, sizeof(TYPE) * mEntryCapacity, nEntries);
subtitle.rar
需积分: 9 9 浏览量
2019-05-16
14:44:24
上传
评论
收藏 44KB RAR 举报
xuhui_7810
- 粉丝: 297
- 资源: 21
最新资源
- pta题库答案c语言之树结构2ListLeaves.zip
- pta题库答案c语言之树结构1树的同构.zip
- 基于C++实现民航飞行与地图简易管理系统可执行程序+说明+详细注释.zip
- pta题库答案c语言之复杂度1最大子列和问题.zip
- 三维装箱问题(Three-Dimensional Bin Packing Problem,3D-BPP)是一个经典的组合优化问题
- 以下是一些关于Linux线程同步的基本概念和方法.txt
- 以下是一个简化的示例,它使用pygame库来模拟烟花动画的框架.txt
- Linux线程同步机制深度解析与实用指南.zip
- PTA题库C语言解题策略与实战.rar
- SVPWM控制技术的simulink建模与仿真【包括simulink模型,参考文献,操作步骤】
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈