All pastes #2046854 Raw Edit

Something

public text v1 · immutable
#2046854 ·published 2011-04-15 15:25 UTC
rendered paste body
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <libavutil/crc.h>

int main(int argc, char *argv[])
{
  int fd = open(argv[1], O_RDONLY);
  uint8_t buffer[38];
  unsigned int offset = 0;
  AVCRC crc_2D[1024];

  int rate = 0;
  int substreams = 0;

  /* search for major sync header first to align */
  memset(buffer, 0, sizeof(buffer));
  while(read(fd, buffer + 4, 1) == 1) {
    ++offset;
    uint32_t syncword = ((((buffer[0] << 8 | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3];
    if (syncword == 0xf8726fba)
    {
      offset -= 9;
      lseek(fd, -9, SEEK_CUR);
      break;
    }
    memmove(buffer, buffer + 1, 4);
  }

  av_crc_init(crc_2D, 0, 16, 0x2D, sizeof(crc_2D));

  /* read the access units */
  while(read(fd, buffer, sizeof(buffer)) == sizeof(buffer)) {
    int      valid    = 1;
    uint16_t length   = ((buffer[0] & 0x0F) << 8 | buffer[1]) << 1;
    uint32_t syncword = ((((buffer[4] << 8 | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7];

    printf("offset: 0x%08x, length: %3d, ", offset, length);

    /* check for a major audio unit */
    if (syncword == 0xf8726fba)
    {
      rate  = (buffer[8] & 0xF0) >> 4;
      if (rate == 0xF)
      {
        rate  = 0;
        valid = 0;
      }
      else
        rate = (rate & 8 ? 44100 : 48000) << (buffer[8] & 7);

      /* verify the CRC */
      if (valid)
      {
        uint16_t crc = av_crc(crc_2D, 0, buffer + 4, 24);
        crc ^= (buffer[29] << 8) | buffer[28];
        valid = ((buffer[31] << 8) | buffer[30]) == crc;
      }

      substreams = (buffer[20] & 0xF0) >> 4;
    }
    else
    {
      /* verify the parity */
      int p = 0;
      uint8_t check = 0;
      for(int i = -1; i < substreams; ++i)
      {
        check ^= buffer[p++];
        check ^= buffer[p++];
        if (i == -1 || buffer[p - 2] & 0x80)
        {
          check ^= buffer[p++];
          check ^= buffer[p++];
        }
      }

      valid = ((((check >> 4) ^ check) & 0xF) == 0xF);
    }

    printf("%s, %dHz, %d substreams\n", valid ? "Valid" : "Invalid", rate, substreams);

    lseek(fd, length - sizeof(buffer), SEEK_CUR);
    offset += length;

    if (!valid)
    {
      printf("Lost Sync\n");
      break;
    }
  }

  close(fd);
}