/**
    \fn mkreformatVorbisHeader
    \brief reformat oggvorbis header to avidemux style
*/
uint8_t mkvHeader::reformatVorbisHeader(mkvTrak *trk)
{
  /*
  The private data contains the first three Vorbis packet in order. The lengths of the packets precedes them. The actual layout is:
Byte 1: number of distinct packets '#p' minus one inside the CodecPrivate block. This should be '2' for current Vorbis headers.
Bytes 2..n: lengths of the first '#p' packets, coded in Xiph-style lacing. The length of the last packet is the length of the CodecPrivate block minus the lengths coded in these bytes minus one.
Bytes n+1..: The Vorbis identification header, followed by the Vorbis comment header followed by the codec setup header.
  */
  uint8_t *oldata=trk->extraData;
  uint32_t oldlen=trk->extraDataLen;
  uint32_t len1,len2,len3;
  uint8_t *head;
      if(*oldata!=2) {printf("[MKV] weird audio, expect problems\n");return 0;}
      // First packet length
      head=oldata+1;
#define READ_LEN(x) \
      x=0; \
      while(*head==0xff)  \
      { \
        x+=0xff; \
        head++; \
      } \
      x+=*head++;

      READ_LEN(len1);
      READ_LEN(len2);
      len3=oldata+oldlen-head;
      if(len3<=len1+len2)
      {
        printf("Error in vorbis header, len3 too small %u %u / %u\n",len1,len2,len3);
        return 0;
      }
      len3-=(len1+len2);
      printf("Found packet len : %u %u %u, total size %u\n",len1,len2,len3,oldlen);
      // Now build our own packet...
      uint8_t *nwdata=new uint8_t[len1+len2+len3+sizeof(uint32_t)*3];
      uint32_t nwlen=len1+len2+len3+sizeof(uint32_t)*3;
      uint8_t *cp=nwdata+sizeof(uint32_t)*3;
      memcpy(cp,head,len1);
      memcpy(cp+len1,head+len1,len2);
      memcpy(cp+len1+len2,head+len1+len2,len3);

      uint32_t *h=(uint32_t *)nwdata;
      h[0]=len1;
      h[1]=len2;
      h[2]=len3;
      // Destroy old datas
      delete [] oldata;
      trk->extraData=nwdata;
      trk->extraDataLen=nwlen;
  return 1;
}
Exemple #2
0
static OP *
read_action(int timeout) {
#ifdef _WIN32
  HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
  DWORD available;

  PeekNamedPipe(hIn, NULL, 0, NULL, &available, NULL);
  if (available == 0)
    return NULL;
#else
  struct pollfd pfd[] = {{0, POLLIN, 0}};
  poll(pfd, 1, timeout);
  if ((pfd[0].revents & (POLLIN | POLLERR | POLLHUP)) == 0)
    return NULL;
#endif
  char op;

  if (read(0, &op, 1) == 0)
    return &eof_op;

  if (op == 'r' || op == 's') {
    char input_buf[9];
    size_t challenges_lengths[16];
    size_t challenges_num, challenges_buf_len = 0, domain_len;
    int i;

    if (!read_n_bytes(input_buf, 8))
      return &eof_op;

    input_buf[8] = '\0';
    READ_LEN(input_buf + 4, challenges_num);
    input_buf[4] = '\0';
    READ_LEN(input_buf, domain_len);

    if (challenges_num >= sizeof(challenges_lengths) / sizeof(challenges_lengths[0]))
      return &eof_op;

    for (i = 0; i < challenges_num; i++) {
      if (!read_n_bytes(input_buf, 4))
        return &eof_op;
      READ_LEN(input_buf, challenges_lengths[i]);
      challenges_buf_len += challenges_lengths[i];
    }

    OP *buf = malloc(domain_len + (sizeof(char *) * (challenges_num + 1)) +
                     challenges_buf_len + challenges_num + 1 + sizeof(OP));
    if (!buf)
      return &eof_op;

    buf->op = op;
    buf->challenges = (char **) (buf + 1);
    buf->domain = (char *) (buf->challenges + challenges_num + 1);
    buf->domain[domain_len] = '\0';

    if (!read_n_bytes(buf->domain, domain_len)) {
      free(buf);
      return &eof_op;
    }

    char *challenge = buf->domain + domain_len + 1;
    for (i = 0; i < challenges_num; i++) {
      buf->challenges[i] = challenge;
      if (!read_n_bytes(buf->challenges[i], challenges_lengths[i])) {
        free(buf);
        return &eof_op;
      }
      challenge[challenges_lengths[i]] = '\0';
      challenge += challenges_lengths[i];
    }
    buf->challenges[challenges_num] = NULL;
    return buf;
  } else
    return &eof_op;
}