当前位置:   article > 正文

Exoplayer(8)-Extoractor解析数据和缓存到内存

Exoplayer(8)-Extoractor解析数据和缓存到内存

前文我们讲到了Exoplayer数据源打开过程, 媒体数据流链接建立好之后会对数据流解析媒体格式解析, 本文我们主要讲Extrator解析和读取数据的六层

ExtractingLoadable.load() ->
BundledExtractorsAdapter.read() →
Mp4Extractor.read() →
Mp4Extractor.readSample() →
TrackOutput.sampleData() →
SampleQueue.sampleData() ->
SampleDataQueue.sampleData() ->

ExtractingLoadable

public void load() throws IOException {
      int result = Extractor.RESULT_CONTINUE;
      while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
        try {
          //初始化Extractor
          progressiveMediaExtractor.init(
              extractorDataSource,
              uri,
              dataSource.getResponseHeaders(),
              position,
              length,
              extractorOutput);
 
          //如果result != Extractor.RESULT_CONTINUE 或者删除播放,退出读取数据
          while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
            //Extractor 读取解析数据
            result = progressiveMediaExtractor.read(positionHolder);           
          }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

BundledExtractorsAdapter

public int read(PositionHolder positionHolder) throws IOException {
    //extractor MP4Extractor实例 extractorInput DefaultExtractorInput实例
    return Assertions.checkNotNull(extractor).read(Assertions.checkNotNull(extractorInput), positionHolder);
  }
  • 1
  • 2
  • 3
  • 4

Mp4Extractor

// 这里我们只关心 STATE_READING_SAMPLE case,
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
    while (true) {
      switch (parserState) {
        case STATE_READING_ATOM_HEADER:
          if (!readAtomHeader(input)) {
            return RESULT_END_OF_INPUT;
          }
          break;
        case STATE_READING_ATOM_PAYLOAD:
          if (readAtomPayload(input, seekPosition)) {
            return RESULT_SEEK;
          }
          break;
        case STATE_READING_SAMPLE:
          // 读取数据
          return readSample(input, seekPosition);
        case STATE_READING_SEF:
          return readSefData(input, seekPosition);
        default:
          throw new IllegalStateException();
      }
    }
  }
 
  private int readSample(ExtractorInput input, PositionHolder positionHolder) throws IOException {
      //循环读取数据,并记录读取数据的长度
      while (sampleBytesWritten < sampleSize) {
        int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten, false);
        sampleBytesRead += writtenBytes;
        sampleBytesWritten += writtenBytes;
        sampleCurrentNalBytesRemaining -= writtenBytes;
      }
    return RESULT_CONTINUE;
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

TrackOutput

default int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException {
    return sampleData(input, length, allowEndOfInput, SAMPLE_DATA_PART_MAIN);
}
  • 1
  • 2
  • 3

SampleQueue

public final int sampleData(
      DataReader input, int length, boolean allowEndOfInput, @SampleDataPart int sampleDataPart)
      throws IOException {
    //sampleDataQueue  是 SampleDataQueue实例
    return sampleDataQueue.sampleData(input, length, allowEndOfInput);
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

SampleDataQueue

public int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException {
    /* 将数据读取到writeAllocationNode.allocation.data 缓存中,
     * writeAllocationNode.allocation.data 保存的是h264, pcm等压缩数据
     * writeAllocationNode.allocation.data 后续会被渲染器读取, 解码渲染
     */
    int bytesAppended =
        input.read(
            writeAllocationNode.allocation.data,
            writeAllocationNode.translateOffset(totalBytesWritten),
            length);
    return bytesAppended;
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/295799
推荐阅读
相关标签
  

闽ICP备14008679号