2011-11-21 10:02:18

 

2011-11-21 10:02:18

ril的问题
实际上就是一个android.jar
找的是avC
设备类型和子类型
注册消息和login返回的消息
其他的类型都是2
注册类型 设备类型和设备子类型
MPEG4Writer
没有发送媒体流了
fopen和fdopen
dump 将所有track的内容都dump出来
dump 描述track的是音频还是视频的?
addSource 每个源就是一个track
startTracks 将每个track开启一下

//计算moovbox的大小
int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
    // This implementation is highly experimental/heurisitic.
    //
    // Statistical analysis shows that metadata usually accounts
    // for a small portion of the total file size, usually < 0.6%.

    // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
    // where 1MB is the common file size limit for MMS application.
    // The default MAX _MOOV_BOX_SIZE value is based on about 3
    // minute video recording with a bit rate about 3 Mbps, because
    // statistics also show that most of the video captured are going
    // to be less than 3 minutes.

    // If the estimation is wrong, we will pay the price of wasting
    // some reserved space. This should not happen so often statistically.
       
    static const int32_t factor = mUse32BitOffset? 1: 2;
    static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
    static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
    int64_t size = MIN_MOOV_BOX_SIZE;
  
     最小是3K
    // Max file size limit is set
   
    if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
        size = mMaxFileSizeLimitBytes * 6 / 1000;
    }

    // Max file duration limit is set
    if (mMaxFileDurationLimitUs != 0) {
        if (bitRate > 0) {
            int64_t size2 =
                ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
            if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
                // When both file size and duration limits are set,
                // we use the smaller limit of the two.
                if (size > size2) {
                    size = size2;
                }
            } else {
                // Only max file duration limit is set
                size = size2;
            }
        }
    }

    if (size < MIN_MOOV_BOX_SIZE) {
        size = MIN_MOOV_BOX_SIZE;
    }

    // Any long duration recording will be probably end up with
    // non-streamable mp4 file.
    if (size > MAX_MOOV_BOX_SIZE) {
        size = MAX_MOOV_BOX_SIZE;
    }

    LOGI("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated"
         " moov size %lld bytes",
         mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
    return factor * size;
}


首先来说3gp文件相当于一个容器,本身没有什么具体的编码解码规则。
我们可以选择编码方式

- AMR narrow-band:编码简称'samr' 常用与语言片段的压缩,可以对声音片段进行最大程度的压缩,但是失真较大,
如果用在音乐文件上结构常常是无法忍受的。

(详情请参考:3GPP TS 26.071: "Mandatory Speech CODEC speech processing functions; AMR Speech CODEC; General description".)

- AMR wideband:编码简称'sawb' 相对AMR narrow-band来说压缩比降低了,品质有所提升可用来压缩音乐。
(详情请参考:3GPP TS 26.171: "AMR Wideband Speech Codec; General Description".)

宽带

- Extended AMR-WB codec编码简称 'sawp'
(详情请参考:
3GPP TS 26.290: "Extended AMR Wideband codec; Transcoding functions".
3GPP TS 26.304: "ANSI-C code for the Floating-point; Extended AMR Wideband codec".
3GPP TS 26.273: "ANSI-C code for the Fixed-point; Extended AMR Wideband codec".

- Enhanced aacPlus and MPEG-4 AAC codec编码简称 'mp4a'
(详情请参考:
3GPP TS 26.401: "General audio codec audio processing functions; Enhanced aacPlus general audio codec; General description".
3GPP TS 26.410: "General audio codec audio processing functions; Enhanced aacPlus general audio codec; Floating-point ANSI-C code".
3GPP TS 26.411: "General audio codec audio processing functions; Enhanced aacPlus general audio codec; Fixed-point ANSI-C code".


- MPEG-4 video codec编码简称'mp4v'
(详情请参考:ISO/IEC 14496-2:2004: "Information technology – Coding of audio-visual objects – Part 2: Visual".)

- H.263 video codec编码简称'h263'
(详情请参考:ITU-T Recommendation H.263 (01/05): "Video coding for low bit rate communication".)


- H.264 video codec编码简称'avc1'
(详情请参考:ITU-T Recommendation H.264 (03/05): "Advanced video coding for generic audiovisual services"
ISO/IEC 14496-10:2005: "Information technology – Coding of audio-visual objects – Part 10: Advanced Video Coding".)


- 3GPP timed text format 编码简称'tx3g'
(详情请参考:3GPP TS 26.245: "Transparent end-to-end packet switched streaming service (PSS); Timed text format".)

start
如果有文件大小限制,那就是要精确的限制文件大小
到底是使用32位偏移还是使用64位偏移
如果是32位系统,最大文件大小只能是2G
使用2字节的NAL长度,还是使用4字节的NAL长度
如果已经是开始了,那么返回,如果是暂停,直接startTracks
获取时间精度,默认为1000
beginBox("ftyp"); 写入ftyp
    beginBox("ftyp");
      {
        int32_t fileType;
        if (param && param->findInt32(kKeyFileType, &fileType) &&
            fileType != OUTPUT_FORMAT_MPEG_4) {
            writeFourcc("3gp4");
        } else {
            writeFourcc("isom");
        }
      }
      writeInt32(0);
      writeFourcc("isom");
      writeFourcc("3gp4");
    endBox();
   
   
    void MPEG4Writer::endBox() {
    CHECK(!mBoxes.empty());

    off_t offset = *--mBoxes.end();
    mBoxes.erase(--mBoxes.end());

    if (mWriteMoovBoxToMemory) {
       int32_t x = htonl(mMoovBoxBufferOffset - offset);
       memcpy(mMoovBoxBuffer + offset, &x, 4);
    } else {
        fseeko(mFile, offset, SEEK_SET);
        writeInt32(mOffset - offset);
        mOffset -= 4;
        fseeko(mFile, mOffset, SEEK_SET);
    }
}
重新写这个头

status_t MPEG4Writer::startWriterThread() {
    LOGV("startWriterThread");

    mDone = false;
    mIsFirstChunk = true;
    mDriftTimeUs = 0;
    for (List<Track *>::iterator it = mTracks.begin();
         it != mTracks.end(); ++it) {
        ChunkInfo info;
        info.mTrack = *it;
        mChunkInfos.push_back(info);
    }
 全部放入到 chunk中
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&mThread, &attr, ThreadWrapper, this);
    pthread_attr_destroy(&attr);
    return OK;
}

写封装

void *MPEG4Writer::ThreadWrapper(void *me) {
    LOGV("ThreadWrapper: %p", me);
    MPEG4Writer *writer = static_cast<MPEG4Writer *>(me);
    writer->threadFunc();
    return NULL;
}


status_t MPEG4Writer::writeOneChunk() {
    LOGV("writeOneChunk");

    // Find the smallest timestamp, and write that chunk out
    // XXX: What if some track is just too slow?
    int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
    Track *track = NULL;
    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
         it != mChunkInfos.end(); ++it) {
        if (!it->mChunks.empty()) {
            List<Chunk>::iterator chunkIt = it->mChunks.begin();
            if (chunkIt->mTimeStampUs < minTimestampUs) {
                minTimestampUs = chunkIt->mTimeStampUs;
                track = it->mTrack;
            }
        }
    }
   
  
    if (track == NULL) {
        LOGV("Nothing to be written after all");
        return OK;
    }

    if (mIsFirstChunk) {
        mIsFirstChunk = false;
    }
    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
         it != mChunkInfos.end(); ++it) {
        if (it->mTrack == track) {
            writeFirstChunk(&(*it));
        }
    }
    return OK;
}

chunk
 
    struct ChunkInfo {
        Track               *mTrack;        // Owner
        List<Chunk>         mChunks;        // Remaining chunks to be written
    };

addSample_l

 

你可能感兴趣的:(2011-11-21 10:02:18)