示例#1
0
void AMRAudioRTPSink::doSpecialFrameHandling(unsigned fragmentationOffset,
					     unsigned char* frameStart,
					     unsigned numBytesInFrame,
					     struct timeval framePresentationTime,
					     unsigned numRemainingBytes) {
  // If this is the 1st frame in the 1st packet, set the RTP 'M' (marker)
  // bit (because this is considered the start of a talk spurt):
  if (isFirstPacket() && isFirstFrameInPacket()) {
    setMarkerBit();
  }

  // If this is the first frame in the packet, set the 1-byte payload
  // header (using CMR 15)
  if (isFirstFrameInPacket()) {
    u_int8_t payloadHeader = 0xF0;
    setSpecialHeaderBytes(&payloadHeader, 1, 0);
  }

  // Set the TOC field for the current frame, based on the "FT" and "Q"
  // values from our source:
  AMRAudioSource* amrSource = (AMRAudioSource*)fSource;
  if (amrSource == NULL) return; // sanity check

  u_int8_t toc = amrSource->lastFrameHeader();
  // Clear the "F" bit, because we're the last frame in this packet: #####
  toc &=~ 0x80;
  setSpecialHeaderBytes(&toc, 1, 1+numFramesUsedSoFar());

  // Important: Also call our base class's doSpecialFrameHandling(),
  // to set the packet's timestamp:
  MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
                                             frameStart, numBytesInFrame,
                                             framePresentationTime,
                                             numRemainingBytes);
}
示例#2
0
void AMRAudioFileSink::afterGettingFrame1(unsigned frameSize,
					  struct timeval presentationTime) {
  AMRAudioSource* source = (AMRAudioSource*)fSource;

  if (!fHaveWrittenHeader && fPerFrameFileNameBuffer == NULL) {
    // Output the appropriate AMR header to the start of the file.
    // This header is defined in RFC 3267, section 5. 
    // (However, we don't do this if we're creating one file per frame.)
    char headerBuffer[100];
    sprintf(headerBuffer, "#!AMR%s%s\n",
	    source->isWideband() ? "-WB" : "",
	    source->numChannels() > 1 ? "_MC1.0" : "");
    unsigned headerLength = strlen(headerBuffer);
    if (source->numChannels() > 1) {
      // Also add a 32-bit channel description field:
      headerBuffer[headerLength++] = 0;
      headerBuffer[headerLength++] = 0;
      headerBuffer[headerLength++] = 0;
      headerBuffer[headerLength++] = source->numChannels();
    }

    addData((unsigned char*)headerBuffer, headerLength, presentationTime);
  }
  fHaveWrittenHeader = True;

  // Add the 1-byte header, before writing the file data proper:
  // (Again, we don't do this if we're creating one file per frame.)
  if (fPerFrameFileNameBuffer == NULL) {
    u_int8_t frameHeader = source->lastFrameHeader();
    addData(&frameHeader, 1, presentationTime);
  }

  // Call the parent class to complete the normal file write with the input data:
  FileSink::afterGettingFrame1(frameSize, presentationTime);
}