示例#1
0
void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
                     const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
                     unsigned int displayWidth, unsigned int displayHeight,
                     double frameRate) {
  EbmlLoc start;
  UInt64 trackID;
  Ebml_StartSubElement(glob, &start, TrackEntry);
  Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
  trackID = generateTrackID(trackNumber);
  Ebml_SerializeUnsigned(glob, TrackUID, trackID);
  Ebml_SerializeString(glob, CodecName, "VP8");  // TODO shouldn't be fixed

  Ebml_SerializeUnsigned(glob, TrackType, 1); // video is always 1
  Ebml_SerializeString(glob, CodecID, codecId);
  {
    EbmlLoc videoStart;
    Ebml_StartSubElement(glob, &videoStart, Video);
    Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
    Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
    if (pixelWidth != displayWidth) {
      Ebml_SerializeUnsigned(glob, DisplayWidth, displayWidth);
    }
    if (pixelHeight != displayHeight) {
      Ebml_SerializeUnsigned(glob, DisplayHeight, displayHeight);
    }
    Ebml_SerializeFloat(glob, FrameRate, frameRate);
    Ebml_EndSubElement(glob, &videoStart); // Video
  }
  Ebml_EndSubElement(glob, &start); // Track Entry
}
示例#2
0
void write_webm_file_header(struct EbmlGlobal *glob,
                            const vpx_codec_enc_cfg_t *cfg,
                            const struct vpx_rational *fps,
                            stereo_format_t stereo_fmt,
                            unsigned int fourcc) {
  EbmlLoc start;
  EbmlLoc trackStart;
  EbmlLoc videoStart;
  unsigned int trackNumber = 1;
  uint64_t trackID = 0;
  unsigned int pixelWidth = cfg->g_w;
  unsigned int pixelHeight = cfg->g_h;

  /* Write the EBML header. */
  Ebml_StartSubElement(glob, &start, EBML);
  Ebml_SerializeUnsigned(glob, EBMLVersion, 1);
  Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1);
  Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4);
  Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8);
  Ebml_SerializeString(glob, DocType, "webm");
  Ebml_SerializeUnsigned(glob, DocTypeVersion, 2);
  Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2);
  Ebml_EndSubElement(glob, &start);

  /* Open and begin writing the segment element. */
  Ebml_StartSubElement(glob, &glob->startSegment, Segment);
  glob->position_reference = ftello(glob->stream);
  glob->framerate = *fps;
  write_webm_seek_info(glob);

  /* Open and write the Tracks element. */
  glob->track_pos = ftello(glob->stream);
  Ebml_StartSubElement(glob, &trackStart, Tracks);

  /* Open and write the Track entry. */
  Ebml_StartSubElement(glob, &start, TrackEntry);
  Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
  glob->track_id_pos = ftello(glob->stream);
  Ebml_SerializeUnsigned32(glob, TrackUID, trackID);
  Ebml_SerializeUnsigned(glob, TrackType, 1);
  Ebml_SerializeString(glob, CodecID,
                       fourcc == VP8_FOURCC ? "V_VP8" : "V_VP9");
  Ebml_StartSubElement(glob, &videoStart, Video);
  Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
  Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
  Ebml_SerializeUnsigned(glob, StereoMode, stereo_fmt);
  Ebml_EndSubElement(glob, &videoStart);

  /* Close Track entry. */
  Ebml_EndSubElement(glob, &start);

  /* Close Tracks element. */
  Ebml_EndSubElement(glob, &trackStart);

  /* Segment element remains open. */
}
int Ebml_WriteWebMSeekInfo(EbmlGlobal *ebml)
{
    int rc = VINF_SUCCESS;

    /* Save the current file pointer */
    uint64_t pos = RTFileTell(ebml->file);

    if (ebml->seek_info_pos)
        rc = RTFileSeek(ebml->file, ebml->seek_info_pos, RTFILE_SEEK_BEGIN, NULL);
    else
        ebml->seek_info_pos = pos;

    {
        uint64_t start;

        if (RT_SUCCESS(rc))
            rc = ebml_StartSubElement(ebml, &start, SeekHead);
        if (RT_SUCCESS(rc))
            rc = Ebml_WriteWebMSeekElement(ebml, Tracks, ebml->track_pos);
        if (RT_SUCCESS(rc))
            rc = Ebml_WriteWebMSeekElement(ebml, Cues, ebml->cue_pos);
        if (RT_SUCCESS(rc))
            rc = Ebml_WriteWebMSeekElement(ebml, Info, ebml->segment_info_pos);
        if (RT_SUCCESS(rc))
            rc = ebml_EndSubElement(ebml, start);
    }
    {
        //segment info
        uint64_t startInfo;
        uint64_t frame_time;

        frame_time = (uint64_t)1000 * ebml->framerate.den / ebml->framerate.num;
        ebml->segment_info_pos = RTFileTell(ebml->file);
        if (RT_SUCCESS(rc))
            rc = ebml_StartSubElement(ebml, &startInfo, Info);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(ebml, TimecodeScale, 1000000);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeFloat(ebml, Segment_Duration,
                                     (double)(ebml->last_pts_ms + frame_time));
        char szVersion[64];
        RTStrPrintf(szVersion, sizeof(szVersion), "vpxenc%",
                    ebml->debug ? vpx_codec_version_str() : "");
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeString(ebml, MuxingApp, szVersion);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeString(ebml, WritingApp, szVersion);
        if (RT_SUCCESS(rc))
            rc = ebml_EndSubElement(ebml, startInfo);
    }
    return rc;
}
//------------------------------------------------------------------
void write_webm_file_header(EbmlGlobal *global, const vpx_codec_enc_cfg_t *cfg, const struct vpx_rational *fps)
{
	off_t start;
	off_t trackStart;
	off_t videoStart;
	unsigned int trackNumber = 1;
	uint64_t trackID = 0;
	unsigned int pixelWidth = cfg->g_w;
	unsigned int pixelHeight = cfg->g_h;

	/* Write the EBML header. */
	Ebml_StartSubElement(global, &start, EBML);
	Ebml_SerializeUnsigned(global, EBMLVersion, 1);
	Ebml_SerializeUnsigned(global, EBMLReadVersion, 1);
	Ebml_SerializeUnsigned(global, EBMLMaxIDLength, 4);
	Ebml_SerializeUnsigned(global, EBMLMaxSizeLength, 8);
	Ebml_SerializeString(global, DocType, "webm");
	Ebml_SerializeUnsigned(global, DocTypeVersion, 2);
	Ebml_SerializeUnsigned(global, DocTypeReadVersion, 2);
	Ebml_EndSubElement(global, &start);

	/* Open and begin writing the segment element. */
	Ebml_StartSubElement(global, &global->startSegment, Segment);
	global->position_reference = ftello(global->stream);
	global->framerate = *fps;
	write_webm_seek_info(global);

	/* Open and write the Tracks element. */
	global->track_pos = ftello(global->stream);
	Ebml_StartSubElement(global, &trackStart, Tracks);

	/* Open and write the Track entry. */
	Ebml_StartSubElement(global, &start, TrackEntry);
	Ebml_SerializeUnsigned(global, TrackNumber, trackNumber);
	global->track_id_pos = ftello(global->stream);
	Ebml_SerializeUnsigned32(global, TrackUID, trackID);
	Ebml_SerializeUnsigned(global, TrackType, 1);
	Ebml_SerializeString(global, CodecID, "V_VP8");
	Ebml_StartSubElement(global, &videoStart, Video);
	Ebml_SerializeUnsigned(global, PixelWidth, pixelWidth);
	Ebml_SerializeUnsigned(global, PixelHeight, pixelHeight);
	Ebml_SerializeUnsigned(global, StereoMode, STEREO_FORMAT_MONO);
	Ebml_EndSubElement(global, &videoStart);

	/* Close Track entry. */
	Ebml_EndSubElement(global, &start);

	/* Close Tracks element. */
	Ebml_EndSubElement(global, &trackStart);

	/* Segment element remains open. */
}
int main(int argc, char *argv[]) {
  // init the datatype we're using for ebml output
  unsigned char data[8192];
  EbmlGlobal ebml;
  ebml.buf = data;
  ebml.offset = 0;
  ebml.length = 8192;

  writeHeader(&ebml);
  {
    EbmlLoc startSegment;
    Ebml_StartSubElement(&ebml, &startSegment, Segment); // segment
    {
      // segment info
      EbmlLoc startInfo;
      Ebml_StartSubElement(&ebml, &startInfo, Info);
      Ebml_SerializeString(&ebml, 0x4D80, "muxingAppLibMkv");
      Ebml_SerializeString(&ebml, 0x5741, "writingAppLibMkv");
      Ebml_EndSubElement(&ebml, &startInfo);
    }

    {
      EbmlLoc trackStart;
      Ebml_StartSubElement(&ebml, &trackStart, Tracks);
      writeVideoTrack(&ebml, 1, 1, "V_MS/VFW/FOURCC", 320, 240, 29.97);
      // writeAudioTrack(&ebml,2,1, "A_VORBIS", 32000, 1, NULL, 0);
      Ebml_EndSubElement(&ebml, &trackStart);
    }

    {
      EbmlLoc clusterStart;
      Ebml_StartSubElement(&ebml, &clusterStart, Cluster); // cluster
      Ebml_SerializeUnsigned(&ebml, Timecode, 0);

      unsigned char someData[4] = {1, 2, 3, 4};
      writeSimpleBlock(&ebml, 1, 0, 1, 0, 0, someData, 4);
      Ebml_EndSubElement(&ebml, &clusterStart);
    }    // end cluster
    Ebml_EndSubElement(&ebml, &startSegment);
  }

  // dump ebml stuff to the file
  FILE *file_out = fopen("test.mkv", "wb");
  size_t bytesWritten = fwrite(data, 1, ebml.offset, file_out);
  fclose(file_out);
  return 0;
}
示例#6
0
void write_webm_seek_info(struct EbmlGlobal *ebml) {
  off_t pos;
  EbmlLoc start;
  EbmlLoc startInfo;
  uint64_t frame_time;
  char version_string[64];

  /* Save the current stream pointer. */
  pos = ftello(ebml->stream);

  if (ebml->seek_info_pos)
    fseeko(ebml->stream, ebml->seek_info_pos, SEEK_SET);
  else
    ebml->seek_info_pos = pos;

  Ebml_StartSubElement(ebml, &start, SeekHead);
  write_webm_seek_element(ebml, Tracks, ebml->track_pos);
  write_webm_seek_element(ebml, Cues, ebml->cue_pos);
  write_webm_seek_element(ebml, Info, ebml->segment_info_pos);
  Ebml_EndSubElement(ebml, &start);

  /* Create and write the Segment Info. */
  if (ebml->debug) {
    strcpy(version_string, "vpxenc");
  } else {
    strcpy(version_string, "vpxenc ");
    strncat(version_string,
            vpx_codec_version_str(),
            sizeof(version_string) - 1 - strlen(version_string));
  }

  frame_time = (uint64_t)1000 * ebml->framerate.den
               / ebml->framerate.num;
  ebml->segment_info_pos = ftello(ebml->stream);
  Ebml_StartSubElement(ebml, &startInfo, Info);
  Ebml_SerializeUnsigned(ebml, TimecodeScale, 1000000);
  Ebml_SerializeFloat(ebml, Segment_Duration,
                      (double)(ebml->last_pts_ms + frame_time));
  Ebml_SerializeString(ebml, 0x4D80, version_string);
  Ebml_SerializeString(ebml, 0x5741, version_string);
  Ebml_EndSubElement(ebml, &startInfo);
}
示例#7
0
void writeHeader(EbmlGlobal *glob) {
  EbmlLoc start;
  Ebml_StartSubElement(glob, &start, EBML);
  Ebml_SerializeUnsigned(glob, EBMLVersion, 1);
  Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1); 
  Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4); 
  Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8); 
  Ebml_SerializeString(glob, DocType, "webm"); 
  Ebml_SerializeUnsigned(glob, DocTypeVersion, 2); 
  Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2); 
  Ebml_EndSubElement(glob, &start);
}
//------------------------------------------------------------------
void write_webm_seek_info(EbmlGlobal *global)
{
	off_t pos;
	off_t start;
	off_t startInfo;
	uint64_t frame_time;
	char version_string[64];

	/* Save the current stream pointer. */
	pos = ftello(global->stream);

	if (global->seek_info_pos)
	{
		fseeko(global->stream, global->seek_info_pos, SEEK_SET);
	}
	else
	{
		global->seek_info_pos = pos;
	}

	Ebml_StartSubElement(global, &start, SeekHead);
	write_webm_seek_element(global, Tracks, global->track_pos);
	write_webm_seek_element(global, Cues, global->cue_pos);
	write_webm_seek_element(global, Info, global->segment_info_pos);
	Ebml_EndSubElement(global, &start);

	/* Create and write the Segment Info. */
	strcpy(version_string, "DesktopCapture v1.0 - libVPX ");
	strncat(version_string, vpx_codec_version_str(), sizeof(version_string) - 1 - strlen(version_string));

	frame_time = (uint64_t) 1000 * global->framerate.den / global->framerate.num;

	global->segment_info_pos = ftello(global->stream);
	Ebml_StartSubElement(global, &startInfo, Info);
	Ebml_SerializeUnsigned(global, TimecodeScale, 1000000);
	Ebml_SerializeFloat(global, Segment_Duration, (double) (global->last_pts_ms + frame_time));
	Ebml_SerializeString(global, MuxingApp, version_string);
	Ebml_SerializeString(global, WritingApp, version_string);
	Ebml_EndSubElement(global, &startInfo);
}
示例#9
0
void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
                     char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
                     double frameRate) {
  EbmlLoc start;
  Ebml_StartSubElement(glob, &start, TrackEntry);
  Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
  UInt64 trackID = generateTrackID(trackNumber);
  Ebml_SerializeUnsigned(glob, TrackUID, trackID);
  Ebml_SerializeString(glob, CodecName, "VP8");  

  Ebml_SerializeUnsigned(glob, TrackType, 1); 
  Ebml_SerializeString(glob, CodecID, codecId);
  {
    EbmlLoc videoStart;
    Ebml_StartSubElement(glob, &videoStart, Video);
    Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
    Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
    Ebml_SerializeFloat(glob, FrameRate, frameRate);
    Ebml_EndSubElement(glob, &videoStart); 
  }
  Ebml_EndSubElement(glob, &start); 
}
示例#10
0
int Ebml_WriteWebMFileHeader(EbmlGlobal                *glob,
                             const vpx_codec_enc_cfg_t *cfg,
                             const struct vpx_rational *fps)
{
    int rc = VINF_SUCCESS;
    {
        uint64_t start;
        rc = ebml_StartSubElement(glob, &start, EBML);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, EBMLVersion, 1);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeString(glob, DocType, "webm");
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, DocTypeVersion, 2);
        if (RT_SUCCESS(rc))
            rc = Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2);
        if (RT_SUCCESS(rc))
            rc = ebml_EndSubElement(glob, start);
    }
    {
        if (RT_SUCCESS(rc))
            rc = ebml_StartSubElement(glob, &glob->startSegment, Segment);
        glob->position_reference = RTFileTell(glob->file);
        glob->framerate = *fps;
        if (RT_SUCCESS(rc))
            rc = Ebml_WriteWebMSeekInfo(glob);
        {
            uint64_t trackStart;
            glob->track_pos = RTFileTell(glob->file);
            if (RT_SUCCESS(rc))
                rc = ebml_StartSubElement(glob, &trackStart, Tracks);
            {
                uint32_t trackNumber = 1;
                uint32_t trackID = 0;

                uint64_t start;
                if (RT_SUCCESS(rc))
                    rc = ebml_StartSubElement(glob, &start, TrackEntry);
                if (RT_SUCCESS(rc))
                    rc = Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
                glob->track_id_pos = RTFileTell(glob->file);
                ebml_SerializeUnsigned32(glob, TrackUID, trackID);
                Ebml_SerializeUnsigned(glob, TrackType, 1); //video is always 1
                Ebml_SerializeString(glob, CodecID, "V_VP8");
                {
                    uint64_t videoStart;
                    if (RT_SUCCESS(rc))
                        rc = ebml_StartSubElement(glob, &videoStart, Video);
                    uint32_t pixelWidth = cfg->g_w;
                    if (RT_SUCCESS(rc))
                        rc = Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
                    uint32_t pixelHeight = cfg->g_h;
                    if (RT_SUCCESS(rc))
                        rc = Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
                    double   frameRate   = (double)fps->num / (double)fps->den;
                    if (RT_SUCCESS(rc))
                        rc = Ebml_SerializeFloat(glob, FrameRate, frameRate);
                    if (RT_SUCCESS(rc))
                        rc = ebml_EndSubElement(glob, videoStart);
                }
                if (RT_SUCCESS(rc))
                    rc = ebml_EndSubElement(glob, start); //Track Entry
            }
            if (RT_SUCCESS(rc))
                rc = ebml_EndSubElement(glob, trackStart);
        }
        // segment element is open
    }
    return rc;
}