Exemple #1
0
static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
                            int *sample_rate)
{
    GetBitContext gb;
    uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
    int ret, sample_blocks, sr_code;

    if (buf_size < 12)
        return AVERROR_INVALIDDATA;

    if ((ret = ff_dca_convert_bitstream(buf, 12, hdr, 12)) < 0)
        return ret;

    init_get_bits(&gb, hdr, 96);

    skip_bits_long(&gb, 39);
    sample_blocks = get_bits(&gb, 7) + 1;
    if (sample_blocks < 8)
        return AVERROR_INVALIDDATA;
    *duration = 256 * (sample_blocks / 8);

    skip_bits(&gb, 20);
    sr_code = get_bits(&gb, 4);
    *sample_rate = avpriv_dca_sample_rates[sr_code];
    if (*sample_rate == 0)
        return AVERROR_INVALIDDATA;

    return 0;
}
Exemple #2
0
int parse_dts_header(DTSParserContext *pContext, DTSHeader *pHeader, uint8_t *pBuffer, unsigned uSize)
{
  if(!pContext) return -1;
  if(!pHeader) return -1;

  unsigned ExtDescriptor = 0, ExtCoding = 0;

  uint8_t dts_buffer[32 + FF_INPUT_BUFFER_PADDING_SIZE] = {0};
  int ret = ff_dca_convert_bitstream(pBuffer, uSize, dts_buffer, 32);

  bool is16be = (AV_RB32(pBuffer) == DCA_MARKER_RAW_BE);

  /* Parse Core Header */
  if (ret >= 0) {
    pHeader->HasCore = 1;

    GetBitContext *gb = pContext->gb;
    init_get_bits(gb, dts_buffer, 32 << 3);

    skip_bits_long(gb, 32);                             /* Sync code */
    skip_bits1(gb);                                     /* Frame type */
    pHeader->SamplesPerBlock  = get_bits(gb, 5) + 1;    /* Samples deficit */
    pHeader->CRCPresent       = get_bits1(gb);          /* CRC present */
    pHeader->Blocks           = get_bits(gb, 7) + 1;    /* Number of Blocks */
    pHeader->FrameSize        = get_bits(gb, 14) + 1;   /* Primary (core) Frame Size */
    pHeader->ChannelLayout    = get_bits(gb, 6);        /* Channel configuration */
    unsigned sample_index     = get_bits(gb, 4);        /* Sample frequency index */
    pHeader->SampleRate       = avpriv_dca_sample_rates[sample_index];
    unsigned bitrate_index    = get_bits(gb, 5);        /* Bitrate index */
    pHeader->Bitrate          = dca_bit_rates[bitrate_index];
    skip_bits1(gb);                                     /* Down mix */
    skip_bits1(gb);                                     /* Dynamic range */
    skip_bits1(gb);                                     /* Time stamp */
    skip_bits1(gb);                                     /* Auxiliary data */
    skip_bits1(gb);                                     /* HDCD */
    ExtDescriptor             = get_bits(gb, 3);        /* External descriptor  */
    ExtCoding                 = get_bits1(gb);          /* Extended coding */
    skip_bits1(gb);                                     /* ASPF */
    pHeader->LFE              = get_bits(gb, 2);        /* LFE */
    skip_bits1(gb);                                     /* Predictor History */
    if(pHeader->CRCPresent)
      skip_bits(gb, 16);                                /* CRC */
    skip_bits1(gb);                                     /* Multirate Interpolator */
    skip_bits(gb, 4);                                   /* Encoder Software Revision */
    skip_bits(gb, 2);                                   /* Copy history */
    pHeader->ES = get_bits1(gb);                        /* ES */
    skip_bits(gb, 2);                                   /* PCMR (source PCM resolution) */
    skip_bits1(gb);                                     /* SUMF (Front Sum/Difference Flag) */
    skip_bits1(gb);                                     /* SUMS (Surround Sum/Difference Flag) */
    skip_bits(gb, 4);                                   /* Dialog Normalization Parameter or Unspecified (dependent on encoder version) */

    // Check some basic validity
    if (uSize < pHeader->FrameSize)
      return -1;
  } else {
    pHeader->HasCore = 0;
  }

  if (pHeader->HasCore && !is16be)
    return 0;

  // DTS-HD parsing
  const uint8_t *pHD = nullptr;
  if (pHeader->HasCore) { // If we have a core, only search after the normal buffer
    if (uSize > (pHeader->FrameSize + 4)) { // at least 4 bytes extra, could probably insert a minimal size of a HD header, but so what
      pHD = find_marker32_position(pBuffer + pHeader->FrameSize, uSize - pHeader->FrameSize, DCA_HD_MARKER);
    }
  } else {
    pHD = find_marker32_position(pBuffer, uSize, DCA_HD_MARKER);
  }
  if (pHD) {
    pHeader->IsHD = 1;
    size_t remaining = uSize - (pHD - pBuffer);
    parse_dts_hd_header(pContext, pHeader, pHD, (unsigned)remaining);

    const uint8_t *pXChHD = find_marker32_position(pHD, remaining, DCA_XCH_MARKER);
    if (pXChHD) {
      size_t remaining = uSize - (pXChHD - pBuffer);
      parse_dts_xch_hd_header(pContext, pHeader, pXChHD, (unsigned)remaining);
    }

    const uint8_t *pXXChHD = find_marker32_position(pHD, remaining, DCA_XXCH_MARKER);
    if (pXXChHD) {
      size_t remaining = uSize - (pXXChHD - pBuffer);
      parse_dts_xxch_hd_header(pContext, pHeader, pXXChHD, (unsigned)remaining);
    }
  }

  // Handle DTS extensions
  if (ExtCoding) {
    size_t coreSize = pHD ? (pHD - pBuffer) : uSize;
    if (ExtDescriptor == 0 || ExtDescriptor == 3) {
      const uint8_t *pXCh = find_marker32_position(pBuffer, coreSize, DCA_XCH_MARKER);
      if (pXCh) {
        size_t remaining = coreSize - (pXCh - pBuffer);
        parse_dts_xch_header(pContext, pHeader, pXCh, (unsigned)remaining);
      }
    }
    if (ExtDescriptor == 6) {
      const uint8_t *pXXCh = find_marker32_position(pBuffer, coreSize, DCA_XXCH_MARKER);
      if (pXXCh) {
        size_t remaining = coreSize - (pXXCh - pBuffer);
        parse_dts_xxch_header(pContext, pHeader, pXXCh, (unsigned)remaining);
      }
    }
  }

  return 0;
}