Ejemplo n.º 1
0
void navRead_DSI(dsi_t *dsi, unsigned char *buffer) {
  int i;

  CHECK_VALUE(sizeof(dsi_t) == DSI_BYTES - 1); // -1 for substream id
  
  memcpy(dsi, buffer, sizeof(dsi_t));

  /* Endian conversions */

  /* dsi dsi gi */
  B2N_32(dsi->dsi_gi.nv_pck_scr);
  B2N_32(dsi->dsi_gi.nv_pck_lbn);
  B2N_32(dsi->dsi_gi.vobu_ea);
  B2N_32(dsi->dsi_gi.vobu_1stref_ea);
  B2N_32(dsi->dsi_gi.vobu_2ndref_ea);
  B2N_32(dsi->dsi_gi.vobu_3rdref_ea);
  B2N_16(dsi->dsi_gi.vobu_vob_idn);

  /* dsi sml pbi */
  B2N_16(dsi->sml_pbi.category);
  B2N_32(dsi->sml_pbi.ilvu_ea);
  B2N_32(dsi->sml_pbi.ilvu_sa);
  B2N_16(dsi->sml_pbi.size);
  B2N_32(dsi->sml_pbi.vob_v_s_s_ptm);
  B2N_32(dsi->sml_pbi.vob_v_e_e_ptm);

  /* dsi sml agli */
  for(i = 0; i < 9; i++) {
    B2N_32(dsi->sml_agli.data[ i ].address);
    B2N_16(dsi->sml_agli.data[ i ].size);
  }

  /* dsi vobu sri */
  B2N_32(dsi->vobu_sri.next_video);
  for(i = 0; i < 19; i++)
    B2N_32(dsi->vobu_sri.fwda[i]);
  B2N_32(dsi->vobu_sri.next_vobu);
  B2N_32(dsi->vobu_sri.prev_vobu);
  for(i = 0; i < 19; i++)
    B2N_32(dsi->vobu_sri.bwda[i]);
  B2N_32(dsi->vobu_sri.prev_video);

  /* dsi synci */
  for(i = 0; i < 8; i++)
    B2N_16(dsi->synci.a_synca[i]);
  for(i = 0; i < 32; i++)
    B2N_32(dsi->synci.sp_synca[i]);

  
  /* Asserts */

  /* dsi dsi gi */
  CHECK_VALUE(dsi->dsi_gi.zero1 == 0);
}
Ejemplo n.º 2
0
void navRead_PCI(pci_t *pci, unsigned char *buffer) {
  int i, j;

  CHECK_VALUE(sizeof(pci_t) == PCI_BYTES - 1); // -1 for substream id
  
  memcpy(pci, buffer, sizeof(pci_t));

  /* Endian conversions  */

  /* pci pci_gi */
  B2N_32(pci->pci_gi.nv_pck_lbn);
  B2N_16(pci->pci_gi.vobu_cat);
  B2N_32(pci->pci_gi.vobu_s_ptm);
  B2N_32(pci->pci_gi.vobu_e_ptm);
  B2N_32(pci->pci_gi.vobu_se_e_ptm);

  /* pci nsml_agli */
  for(i = 0; i < 9; i++)
    B2N_32(pci->nsml_agli.nsml_agl_dsta[i]);

  /* pci hli hli_gi */
  B2N_16(pci->hli.hl_gi.hli_ss);
  B2N_32(pci->hli.hl_gi.hli_s_ptm);
  B2N_32(pci->hli.hl_gi.hli_e_ptm);
  B2N_32(pci->hli.hl_gi.btn_se_e_ptm);

  /* pci hli btn_colit */
  for(i = 0; i < 3; i++)
    for(j = 0; j < 2; j++)
      B2N_32(pci->hli.btn_colit.btn_coli[i][j]);

  /* NOTE: I've had to change the structure from the disk layout to get
   * the packing to work with Sun's Forte C compiler. */
  
  /* pci hli btni */
  for(i = 0; i < 36; i++) {
    char tmp[sizeof(pci->hli.btnit[i])], swap;
    memcpy(tmp, &(pci->hli.btnit[i]), sizeof(pci->hli.btnit[i]));
    /* Byte 4 to 7 are 'rotated' was: ABCD EFGH IJ is: ABCG DEFH IJ */
    swap   = tmp[6]; 
    tmp[6] = tmp[5];
    tmp[5] = tmp[4];
    tmp[4] = tmp[3];
    tmp[3] = swap;
    
    /* Then there are the two B2N_24(..) calls */
#ifndef WORDS_BIGENDIAN
    swap = tmp[0];
    tmp[0] = tmp[2];
    tmp[2] = swap;
    
    swap = tmp[4];
    tmp[4] = tmp[6];
    tmp[6] = swap;
#endif
    memcpy(&(pci->hli.btnit[i]), tmp, sizeof(pci->hli.btnit[i]));
  }


#ifndef NDEBUG
  /* Asserts */

  /* pci pci gi */ 
  CHECK_VALUE(pci->pci_gi.zero1 == 0);

  /* pci hli hli_gi */
  CHECK_VALUE(pci->hli.hl_gi.zero1 == 0);
  CHECK_VALUE(pci->hli.hl_gi.zero2 == 0);
  CHECK_VALUE(pci->hli.hl_gi.zero3 == 0);
  CHECK_VALUE(pci->hli.hl_gi.zero4 == 0);
  CHECK_VALUE(pci->hli.hl_gi.zero5 == 0);

  /* Are there buttons defined here? */
  if((pci->hli.hl_gi.hli_ss & 0x03) != 0) {
    CHECK_VALUE(pci->hli.hl_gi.btn_ns != 0); 
    CHECK_VALUE(pci->hli.hl_gi.btngr_ns != 0); 
  } else {
    CHECK_VALUE((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0) 
	   || (pci->hli.hl_gi.btn_ns == 0 && pci->hli.hl_gi.btngr_ns == 0));
  }

  /* pci hli btnit */
  for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) {
    for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) {
      int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j;
      CHECK_VALUE(pci->hli.btnit[n].zero1 == 0);
      CHECK_VALUE(pci->hli.btnit[n].zero2 == 0);
      CHECK_VALUE(pci->hli.btnit[n].zero3 == 0);
      CHECK_VALUE(pci->hli.btnit[n].zero4 == 0);
      CHECK_VALUE(pci->hli.btnit[n].zero5 == 0);
      CHECK_VALUE(pci->hli.btnit[n].zero6 == 0);
      
      if (j < pci->hli.hl_gi.btn_ns) {	
	CHECK_VALUE(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end);
	CHECK_VALUE(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end);
	CHECK_VALUE(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns);
	CHECK_VALUE(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns);
	CHECK_VALUE(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns);
	CHECK_VALUE(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns);
	//vmcmd_verify(pci->hli.btnit[n].cmd);
      } else {
	int k;
	CHECK_VALUE(pci->hli.btnit[n].btn_coln == 0);
	CHECK_VALUE(pci->hli.btnit[n].auto_action_mode == 0);
	CHECK_VALUE(pci->hli.btnit[n].x_start == 0);
	CHECK_VALUE(pci->hli.btnit[n].y_start == 0);
	CHECK_VALUE(pci->hli.btnit[n].x_end == 0);
	CHECK_VALUE(pci->hli.btnit[n].y_end == 0);
	CHECK_VALUE(pci->hli.btnit[n].up == 0);
	CHECK_VALUE(pci->hli.btnit[n].down == 0);
	CHECK_VALUE(pci->hli.btnit[n].left == 0);
	CHECK_VALUE(pci->hli.btnit[n].right == 0);
	for (k = 0; k < 8; k++)
	  CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] == 0); //CHECK_ZERO?
      }
    }
  }
#endif /* !NDEBUG */
}
Ejemplo n.º 3
0
static ifo_handle_t *
ifoReadVGMI(int file, ifo_handle_t *ifofile)
{
	off_t	offset;
	Uint	counter;
	UInt32_t sector;
	UInt16_t titles;

	vmgi_mat_t *vmgi_mat;
	tt_srpt_t *tt_srpt;

	/* Make the VTS part null */
	ifofile->vtsi_mat = NULL;

	vmgi_mat = (vmgi_mat_t *)e_malloc(sizeof (vmgi_mat_t));
	if (!vmgi_mat) {
/*		fprintf(stderr, "Memmory allocation error\n");*/
		free(ifofile);
		return (0);
	}

	ifofile->vmgi_mat = vmgi_mat;

	/* Last sector of VMG i.e. last sector of BUP */

	offset = 12;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		ifoClose(ifofile);
		return (0);
	}

	if (read(file, &sector, sizeof (sector)) != sizeof (sector)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		ifoClose(ifofile);
		return (0);
	}

	B2N_32(sector);

	vmgi_mat->vmg_last_sector = sector;

	/* Last sector of IFO */

	offset = 28;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		ifoClose(ifofile);
		return (0);
	}


	if (read(file, &sector, sizeof (sector)) != sizeof (sector)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		ifoClose(ifofile);
		return (0);
	}

	B2N_32(sector);

	vmgi_mat->vmgi_last_sector = sector;


	/* Number of VTS i.e. title sets */

	offset = 62;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		ifoClose(ifofile);
		return (0);
	}


	if (read(file, &titles, sizeof (titles)) != sizeof (titles)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		ifoClose(ifofile);
		return (0);
	}

	B2N_16(titles);

	vmgi_mat->vmg_nr_of_title_sets = titles;


	/* Star sector of VMG Menu VOB */

	offset = 192;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		ifoClose(ifofile);
		return (0);
	}


	if (read(file, &sector, sizeof (sector)) != sizeof (sector)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		ifoClose(ifofile);
		return (0);
	}

	B2N_32(sector);

	vmgi_mat->vmgm_vobs = sector;


	/* Sector offset to TT_SRPT */

	offset = 196;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		ifoClose(ifofile);
		return (0);
	}


	if (read(file, &sector, sizeof (sector)) != sizeof (sector)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		ifoClose(ifofile);
		return (0);
	}

	B2N_32(sector);

	vmgi_mat->tt_srpt = sector;

	tt_srpt = (tt_srpt_t *)e_malloc(sizeof (tt_srpt_t));
	if (!tt_srpt) {
/*		fprintf(stderr, "Memmory allocation error\n");*/
		ifoClose(ifofile);
		return (0);
	}

	ifofile->tt_srpt = tt_srpt;


	/* Number of titles in TT_SRPT */

	offset = 2048 * vmgi_mat->tt_srpt;

	if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGESEEK);
#else
		printf(stderr, MSGESEEK);
#endif
		return (0);
	}

	if (read(file, &titles, sizeof (titles)) != sizeof (titles)) {
#ifdef	USE_LIBSCHILY
		errmsg(MSGEREAD);
#else
		printf(stderr, MSGEREAD);
#endif
		return (0);
	}

	B2N_16(titles);

	tt_srpt->nr_of_srpts = titles;

	tt_srpt->title = (title_info_t *)e_malloc(sizeof (title_info_t) * tt_srpt->nr_of_srpts);
	if (!tt_srpt->title) {
/*		fprintf(stderr, "Memmory allocation error\n");*/
		ifoClose(ifofile);
		return (0);
	}

	/* Start sector of each title in TT_SRPT */

	for (counter = 0; counter < tt_srpt->nr_of_srpts; counter++) {
		offset = (2048 * vmgi_mat->tt_srpt) + 8 + (counter * 12) + 8;
		if (lseek(file, offset, SEEK_SET) != offset) {
#ifdef	USE_LIBSCHILY
			errmsg(MSGESEEK);
#else
			printf(stderr, MSGESEEK);
#endif
			ifoClose(ifofile);
			return (0);
		}

		if (read(file, &sector, sizeof (sector)) != sizeof (sector)) {
#ifdef	USE_LIBSCHILY
			errmsg(MSGEREAD);
#else
			printf(stderr, MSGEREAD);
#endif
			ifoClose(ifofile);
			return (0);
		}

		B2N_32(sector);

		tt_srpt->title[counter].title_set_sector = sector;

	}
	return (ifofile);
}
Ejemplo n.º 4
0
void CMediaSource::ProcessAudioFrame(
				     u_int8_t* frameData,
				     u_int32_t frameDataLength,
				     Timestamp srcFrameTimestamp)
{
  if (m_audioSrcFrameNumber == 0) {
    if (!m_sourceVideo || m_videoSrcFrameNumber == 0) {
      m_encodingStartTimestamp = GetTimestamp();
    }
    m_audioStartTimestamp = srcFrameTimestamp;
#ifdef DEBUG_AUDIO_SYNC
    debug_message("m_audioStartTimestamp = "U64, m_audioStartTimestamp);
#endif
  }

  if (m_audioDstFrameNumber == 0) {
    // we wait until we see the first encoded frame.
    // this is because encoders usually buffer the first few
    // raw audio frames fed to them, and this number varies
    // from one encoder to another
    m_audioEncodingStartTimestamp = srcFrameTimestamp;
  }

  // we calculate audioSrcElapsedDuration by taking the current frame's
  // timestamp and subtracting the audioEncodingStartTimestamp (and NOT
  // the audioStartTimestamp).
  // this way, we just need to compare audioSrcElapsedDuration with 
  // audioDstElapsedDuration (which should match in the ideal case),
  // and we don't have to compensate for the lag introduced by the initial
  // buffering of source frames in the encoder, which may vary from
  // one encoder to another
  m_audioSrcElapsedDuration = srcFrameTimestamp - m_audioEncodingStartTimestamp;
  m_audioSrcFrameNumber++;

#if 0 
  // not needed
  if (resync) {
    // flush preEncodingBuffer
    m_audioPreEncodingBufferLength = 0;

    // change dst sample numbers to account for gap
    m_audioDstSampleNumber = m_audioDstRawSampleNumber
      = DstTicksToSamples(m_audioSrcElapsedDuration);
    error_message("Received resync");
  }
#endif

  bool pcmMalloced = false;
  bool pcmBuffered;
  u_int8_t* pcmData = frameData;
  u_int32_t pcmDataLength = frameDataLength;

  if (m_audioSrcChannels != m_audioDstChannels) {
    // Convert the channels if they don't match
    // we either double the channel info, or combine
    // the left and right
    uint32_t samples = SrcBytesToSamples(frameDataLength);
    uint32_t dstLength = DstSamplesToBytes(samples);
    pcmData = (u_int8_t *)Malloc(dstLength);
    pcmDataLength = dstLength;
    pcmMalloced = true;

    int16_t *src = (int16_t *)frameData;
    int16_t *dst = (int16_t *)pcmData;
    if (m_audioSrcChannels == 1) {
      // 1 channel to 2
      for (uint32_t ix = 0; ix < samples; ix++) {
	*dst++ = *src;
	*dst++ = *src++;
      }
    } else {
      // 2 channels to 1
      for (uint32_t ix = 0; ix < samples; ix++) {
	int32_t sum = *src++;
	sum += *src++;
	sum /= 2;
	if (sum < -32768) sum = -32768;
	else if (sum > 32767) sum = 32767;
	*dst++ = sum & 0xffff;
      }
    }
  }

  // resample audio, if necessary
  if (m_audioSrcSampleRate != m_audioDstSampleRate) {
    ResampleAudio(pcmData, pcmDataLength);

    // resampled data is now available in m_audioPreEncodingBuffer
    pcmBuffered = true;

  } else if (m_audioSrcSamplesPerFrame != m_audioDstSamplesPerFrame) {
    // reframe audio, if necessary
    // e.g. MP3 is 1152 samples/frame, AAC is 1024 samples/frame

    // add samples to end of m_audioBuffer
    // InitAudio() ensures that buffer is large enough
    memcpy(
	   &m_audioPreEncodingBuffer[m_audioPreEncodingBufferLength],
	   pcmData,
	   pcmDataLength);

    m_audioPreEncodingBufferLength += pcmDataLength;

    pcmBuffered = true;

  } else {
    pcmBuffered = false;
  }

  // LATER restructure so as get rid of this label, and goto below
 pcmBufferCheck:

  if (pcmBuffered) {
    u_int32_t samplesAvailable =
      DstBytesToSamples(m_audioPreEncodingBufferLength);

    // not enough samples collected yet to call encode or forward
    if (samplesAvailable < m_audioDstSamplesPerFrame) {
      return;
    }
    if (pcmMalloced) {
      free(pcmData);
      pcmMalloced = false;
    }

    // setup for encode/forward
    pcmData = &m_audioPreEncodingBuffer[0];
    pcmDataLength = DstSamplesToBytes(m_audioDstSamplesPerFrame);
  }


  // encode audio frame
  if (m_pConfig->m_audioEncode) {
    Duration frametime = DstSamplesToTicks(DstBytesToSamples(frameDataLength));

#ifdef DEBUG_AUDIO_SYNC
    debug_message("asrc# %d srcDuration="U64" dst# %d dstDuration "U64,
                  m_audioSrcFrameNumber, m_audioSrcElapsedDuration,
                  m_audioDstFrameNumber, m_audioDstElapsedDuration);
#endif

    // destination gets ahead of source
    // This has been observed as a result of clock frequency drift between
    // the sound card oscillator and the system mainbord oscillator
    // Example: If the sound card oscillator has a 'real' frequency that
    // is slightly larger than the 'rated' frequency, and we are sampling
    // at 32kHz, then the 32000 samples acquired from the sound card
    // 'actually' occupy a duration of slightly less than a second.
    // 
    // The clock drift is usually fraction of a Hz and takes a long
    // time (~ 20-30 minutes) before we are off by one frame duration

    if (m_audioSrcElapsedDuration + frametime < m_audioDstElapsedDuration) {
      debug_message("audio: dropping frame, SrcElapsedDuration="U64" DstElapsedDuration="U64,
                    m_audioSrcElapsedDuration, m_audioDstElapsedDuration);
      return;
    }

    // source gets ahead of destination
    // We tolerate a difference of 3 frames since A/V sync is usually
    // noticeable after that. This way we give the encoder a chance to pick up
    if (m_audioSrcElapsedDuration > (3 * frametime) + m_audioDstElapsedDuration) {
      int j = (int) (DstTicksToSamples(m_audioSrcElapsedDuration
                                       + (2 * frametime)
                                       - m_audioDstElapsedDuration)
                     / m_audioDstSamplesPerFrame);
      debug_message("audio: Adding %d silence frames", j);
      for (int k=0; k<j; k++)
        AddSilenceFrame();
    }

    //Timestamp encodingStartTimestamp = GetTimestamp();

    bool rc = m_audioEncoder->EncodeSamples(
                                            (int16_t*)pcmData,
                                            m_audioDstSamplesPerFrame,
                                            m_audioDstChannels);

    if (!rc) {
      debug_message("failed to encode audio");
      return;
    }

    // Disabled since we are not taking into account audio drift anymore
    /*
    Duration encodingTime =  (GetTimestamp() - encodingStartTimestamp);
    if (m_sourceRealTime && m_videoSource) {
      Duration drift;
      if (frametime <= encodingTime) {
        drift = encodingTime - frametime;
        m_videoSource->AddEncodingDrift(drift);
      }
    }
    */

    ForwardEncodedAudioFrames();

  }

  //Forward PCM Frames to Feeder Sink
  if ((m_pConfig->GetBoolValue(CONFIG_FEEDER_SINK_ENABLE) &&
       frameDataLength > 0)) {
    // make a copy of the pcm data if needed
    u_int8_t* FwdedData;

	FwdedData = (u_int8_t*)Malloc(frameDataLength);
	memcpy(FwdedData, frameData, frameDataLength);

    CMediaFrame* pFrame =
      new CMediaFrame(
		      RAWPCMAUDIOFRAME,
		      FwdedData,
		      frameDataLength,
		      srcFrameTimestamp,
		      0,
		      m_audioDstSampleRate);

   ForwardFrame(pFrame);
  }
  
  // if desired, forward raw audio to sinks
  if (m_pConfig->SourceRawAudio() && pcmDataLength > 0) {

    // make a copy of the pcm data if needed
    u_int8_t* pcmForwardedData;

    if (!pcmMalloced) {
      pcmForwardedData = (u_int8_t*)Malloc(pcmDataLength);
      memcpy(pcmForwardedData, pcmData, pcmDataLength);
    } else {
      pcmForwardedData = pcmData;
      pcmMalloced = false;
    }
#ifndef WORDS_BIGENDIAN
    // swap byte ordering so we have big endian to write into
    // the file.
    uint16_t *pdata = (uint16_t *)pcmForwardedData;
    for (uint32_t ix = 0; 
	 ix < pcmDataLength; 
	 ix += sizeof(uint16_t),pdata++) {
      uint16_t swap = *pdata;
      *pdata = B2N_16(swap);
    }
#endif

    CMediaFrame* pFrame =
      new CMediaFrame(
		      PCMAUDIOFRAME, 
		      pcmForwardedData, 
		      pcmDataLength,
		      m_audioStartTimestamp 
		      + DstSamplesToTicks(m_audioDstRawSampleNumber),
		      DstBytesToSamples(pcmDataLength),
		      m_audioDstSampleRate);
    ForwardFrame(pFrame);

    m_audioDstRawSampleNumber += SrcBytesToSamples(pcmDataLength);
    m_audioDstRawFrameNumber++;
  }

  if (pcmMalloced) {
    free(pcmData);
  }

  if (pcmBuffered) {
    m_audioPreEncodingBufferLength -= pcmDataLength;
    memcpy(
	   &m_audioPreEncodingBuffer[0],
	   &m_audioPreEncodingBuffer[pcmDataLength],
	   m_audioPreEncodingBufferLength);

    goto pcmBufferCheck;
  }

}