static float MPEG1or2ProgramStreamFileDuration(UsageEnvironment& env,
					       char const* fileName,
					       unsigned& fileSize) {
  FramedSource* dataSource = NULL;
  float duration = 0.0; // until we learn otherwise
  fileSize = 0; // ditto

  do {
    // Open the input file as a 'byte-stream file source':
    ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(env, fileName);
    if (fileSource == NULL) break;
    dataSource = fileSource;

    fileSize = (unsigned)(fileSource->fileSize());
    if (fileSize == 0) break;

    // Create a MPEG demultiplexor that reads from that source.
    MPEG1or2Demux* baseDemux = MPEG1or2Demux::createNew(env, dataSource, True);
    if (baseDemux == NULL) break;

    // Create, from this, a source that returns raw PES packets:
    dataSource = baseDemux->newRawPESStream();

    // Read the first time code from the file:
    float firstTimeCode;
    if (!getMPEG1or2TimeCode(dataSource, *baseDemux, True, firstTimeCode)) break;

    // Then, read the last time code from the file.
    // (Before doing this, flush the demux's input buffers,
    //  and seek towards the end of the file, for efficiency.)
    baseDemux->flushInput();
    unsigned const startByteFromEnd = 100000;
    unsigned newFilePosition
      = fileSize < startByteFromEnd ? 0 : fileSize - startByteFromEnd;
    if (newFilePosition > 0) fileSource->seekToByteAbsolute(newFilePosition);

    float lastTimeCode;
    if (!getMPEG1or2TimeCode(dataSource, *baseDemux, False, lastTimeCode)) break;

    // Take the difference between these time codes as being the file duration:
    float timeCodeDiff = lastTimeCode - firstTimeCode;
    if (timeCodeDiff < 0) break;
    duration = timeCodeDiff;
  } while (0);

  Medium::close(dataSource);
  return duration;
}
int main(int argc, char **argv)
{
    // Begin by setting up our usage environment:
    TaskScheduler *scheduler = BasicTaskScheduler::createNew();
    env = BasicUsageEnvironment::createNew(*scheduler);

    // Open the input file as a 'byte-stream file source':
    FramedSource *inputSource = ByteStreamFileSource::createNew(*env, inputFileName);
    if (inputSource == NULL)
    {
        *env << "Unable to open file \"" << inputFileName
             << "\" as a byte-stream file source\n";
        exit(1);
    }

    // Create a MPEG demultiplexor that reads from that source.
    MPEG1or2Demux *baseDemultiplexor = MPEG1or2Demux::createNew(*env, inputSource);

    // Create, from this, a source that returns raw PES packets:
    MPEG1or2DemuxedElementaryStream *pesSource = baseDemultiplexor->newRawPESStream();

    // And, from this, a filter that converts to MPEG-2 Transport Stream frames:
    FramedSource *tsFrames
    = MPEG2TransportStreamFromPESSource::createNew(*env, pesSource);

    // Open the output file as a 'file sink':
    MediaSink *outputSink = FileSink::createNew(*env, outputFileName);
    if (outputSink == NULL)
    {
        *env << "Unable to open file \"" << outputFileName << "\" as a file sink\n";
        exit(1);
    }

    // Finally, start playing:
    *env << "Beginning to read...\n";
    outputSink->startPlaying(*tsFrames, afterPlaying, NULL);

    env->taskScheduler().doEventLoop(); // does not return

    return 0; // only to prevent compiler warning
}
void CProgramToTransportStreamRecorder::Initialize(wchar_t* fileNameOut)
{
	LogDebug(L"CProgramToTransportStreamRecorder::Initialize %s", fileNameOut);
	m_BufferThreadActive=false;
	m_buffer.Clear();


	m_inputSource = CMemoryStreamSource::createNew(*m_env, "",m_buffer);
	if (m_inputSource == NULL) 
	{
		*m_env << "Unable to open memorystream as a byte-stream source\n";
		return;
	}

	// Create a MPEG demultiplexor that reads from that source.
	MPEG1or2Demux* baseDemultiplexor = MPEG1or2Demux::createNew(*m_env, m_inputSource);

	// Create, from this, a source that returns raw PES packets:
	MPEG1or2DemuxedElementaryStream* pesSource = baseDemultiplexor->newRawPESStream();

	// And, from this, a filter that converts to MPEG-2 Transport Stream frames:
	m_tsFrames  = MPEG2TransportStreamFromPESSource::createNew(*m_env, pesSource);
	((MPEG2TransportStreamFromPESSource*) m_tsFrames)->SetSourceType(m_iProgramType);

	m_outputSink = CFileSinkRecorder::createNew(*m_env, fileNameOut);
	if (m_outputSink == NULL) 
	{
		*m_env << "Unable to open file \"" << fileNameOut << "\" as a file sink\n";
		return;
	}
	m_buffer.Clear();
	m_iPacketsToSkip=100;
	//StartBufferThread();
	m_bSendVideoAudioObserverEvents = true;
	m_bStarting=true;
	m_bRunning=true;
}