谈一谈 live555 (*.mkv) track1 和 track2 的信息获取

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/engineer_james/article/details/81810127

发生时间 在处理Describe 请求

在处理describe 请求的时候 DynamicRTSPServer::lookupServerMediaSession ,rtsp服务器会查找SDP信息并且创建,包括查找track1和track2 的信息即 音频视频轨道信息

live555 处理 请求消息 二 “DESCRIBE 分析了为什么会处理 lookupServerMediaSession 函数

具体的判断 视频轨道 track1 和音频轨道 track2过程如下:
track

简单跟一下,就是代码回调的过程

解析文件 获取track1 track2

ByteStreamFileSource 读取文件内容

void ByteStreamFileSource::doReadFromFile() {
//...
  fMaxSize = (unsigned)fNumBytesToStream;
  fFrameSize = fread(fTo, 1, fMaxSize, fFid);
 //..
}

ByteStreamFileSource 负责读取文件的内容 ,最后读取的fMaxSize 个字节,保存在指针变量fTo指向的内存中,默认fMaxSize = 15000,所以内存中有15000个字节

根据 流程图中,首先需要在MatroskaFileParser::parseTrack()读取音视频轨道信息

Boolean MatroskaFileParser::parseTrack() {
  // Read and process each Matroska header, until we get to the end of the Track:

  while (fCurOffsetInFile < fLimitOffsetInFile) {
    while (!parseEBMLIdAndSize(id, size)) {} //从内存中读取信息   音视频框架EBML

    switch (id.val()) {
      case MATROSKA_ID_TRACK_ENTRY: { // 'Track Entry' header: enter this
        // Create a new "MatroskaTrack" object for this entry:
        if (track != NULL && track->trackNumber == 0) delete track; 
        track = new MatroskaTrack;
    break;
      }
      case MATROSKA_ID_TRACK_NUMBER: {
            unsigned trackNumber;
            if (parseEBMLVal_unsigned(size, trackNumber)) {

                  if (track != NULL && trackNumber != 0) {
                    track->trackNumber = trackNumber;
                    fOurFile.addTrack(track, trackNumber);
                  }
            }
      break;
    }
    case: ....
    case:....
   }
  return True; // we're done parsing track entries
}

parseEBMLIdAndSize 读取数据过程如下
parseEBMLIdAndSize
所以将读出的15000个字节其中第一个字节保存在num.data[i] 然后计算出id.val()

当MATROSKA_ID_TRACK_NUMBER == id.val() 就把track1 track2的信息用
fOurFile.addTrack(track, trackNumber)保存

因为 while 循环,而id.val() 不断的计算,会轮询case 情况

u_int64_t EBMLNumber::val() const {
  u_int64_t result = 0;

  for (unsigned i = 0; i < len; ++i) {
    result = result*256 + data[i];
  }

  return result;
}

所以case MATROSKA_ID_TRACK_ENTRY 执行完后执行 case MATROSKA_ID_TRACK_NUMBER
然后执行后面的case 有关track其他的信息
trackType = audio video subtitle? 以及 重要的信息 mimeType = video/H264 和 A_AAC

为了验证如何创建 track1 和track2 的,我加了log,就可以知道如何执行代码

id.val() = MATROSKA_ID_TRACK_ENTRY
id.val() = MATROSKA_ID_TRACK_NUMBER
trackNumber = 1
id.val() = MATROSKA_ID_TRACK_TYPE
id.val() = MATROSKA_ID_CODEC
id.val() = MATROSKA_ID_LANGUAGE
id.val() = MATROSKA_ID_VIDEO
id.val() = MATROSKA_ID_PIXEL_WIDTH
id.val() = MATROSKA_ID_PIXEL_HEIGHT
id.val() = MATROSKA_ID_DISPLAY_WIDTH
id.val() = MATROSKA_ID_DISPLAY_HEIGHT
id.val() = MATROSKA_ID_CODEC_PRIVATE
id.val() = MATROSKA_ID_DEFAULT_DURATION
id.val() = MATROSKA_ID_TRACK_ENTRY
id.val() = MATROSKA_ID_TRACK_NUMBER
trackNumber = 2
id.val() = MATROSKA_ID_TRACK_TYPE
id.val() = MATROSKA_ID_CODEC
id.val() = MATROSKA_ID_CODEC_PRIVATE
id.val() = MATROSKA_ID_DEFAULT_DURATION
id.val() = MATROSKA_ID_AUDIO
id.val() = MATROSKA_ID_SAMPLING_FREQUENCY
id.val() = MATROSKA_ID_CHANNELS

这样track1 和track2信息保存在fTrackTable 中

//保存轨道信息
void MatroskaFile::addTrack(MatroskaTrack* newTrack, unsigned trackNumber) {
  fTrackTable->add(newTrack, trackNumber);
}
//查找轨道信息
MatroskaTrack* MatroskaFile::lookup(unsigned trackNumber) const {
  return fTrackTable->lookup(trackNumber);
}

解析完成后,就开始回调函数,在回调中会取出fTrackTable 轨道信息

void MatroskaFileParser::continueParsing() {
  if (fInputSource != NULL) {
    if (fInputSource->isCurrentlyAwaitingData()) return; 
    if (!parse()) {
      return;
    }
  }
  // We successfully parsed the file.  Call our 'done' function now:
  if (fOnEndFunc != NULL) (*fOnEndFunc)(fOnEndClientData);
}

MatroskaFile::handleEndOfTrackHeaderParsing() 会取出轨道信息,最后
在 MatroskaFileServerDemux::newServerMediaSubsession 创建轨道,因为 DynamicRTSPServer while 循环创建所有track,最后加入subseesion中

    while ((smss = creationState.demux->newServerMediaSubsession()) != NULL) {
      sms->addSubsession(smss);
    }

果然看完协议后,就知道 session用来干嘛的,track1 track2 获取过程解析完毕,也顺便知道如何读取*.mkv 文件


猜你喜欢

转载自blog.csdn.net/engineer_james/article/details/81810127
今日推荐