blob: 1c8d7425c37875e30f7c2dd62c5bf113a69b5d86 [file] [log] [blame]
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#pragma once
#include "scratchbuf.hpp"
#include "webmmuxebmlio.hpp"
#include "webmmuxstreamvideo.hpp"
#include "webmmuxstreamaudio.hpp"
#include <list>
namespace WebmMuxLib
{
class Context
{
Context(const Context&);
Context& operator=(const Context&);
public:
EbmlIO::File m_file;
WebmUtil::EbmlScratchBuf m_buf;
std::wstring m_writing_app;
Context();
~Context();
void SetVideoStream(StreamVideo*);
//TODO: this needs to liberalized to handle multiple audio streams.
void SetAudioStream(StreamAudio*);
void Open(IStream*);
void Close();
void NotifyVideoFrame(StreamVideo*, StreamVideo::VideoFrame*);
int NotifyVideoEOS(StreamVideo*);
void FlushVideo(StreamVideo*);
bool WaitVideo() const;
void NotifyAudioFrame(StreamAudio*, StreamAudio::AudioFrame*);
int NotifyAudioEOS(StreamAudio*);
void FlushAudio(StreamAudio*);
bool WaitAudio() const;
ULONG GetTimecodeScale() const;
ULONG GetTimecode() const; //of frame most recently written to file
bool GetLiveMuxMode() const;
void SetLiveMuxMode(bool is_live);
void BufferData();
void FlushBufferedData();
private:
StreamVideo* m_pVideo;
StreamAudio* m_pAudio; //TODO: accept multiple audio streams
void Final();
void WriteEbmlHeader();
void InitSegment();
void FinalSegment();
void InitFirstSeekHead();
void FinalFirstSeekHead();
void WriteSeekEntry(ULONG, __int64);
void InitInfo();
void FinalInfo();
void WriteTrack();
__int64 m_segment_pos;
__int64 m_seekhead_pos;
__int64 m_info_pos;
__int64 m_track_pos;
__int64 m_cues_pos;
__int64 m_duration_pos;
const ULONG m_timecode_scale; //TODO: video vs. audio
ULONG m_max_timecode; //unscaled
struct Keyframe
{
ULONG m_timecode; //unscaled
ULONG m_block; //1-based number of block within cluster
Keyframe(); //needed for std::list
Keyframe(ULONG timecode, ULONG block);
};
struct Cluster
{
//absolute pos within file (NOT offset relative to segment)
__int64 m_pos;
ULONG m_timecode;
typedef std::list<Keyframe> keyframes_t;
keyframes_t m_keyframes;
};
typedef std::list<Cluster> clusters_t;
clusters_t m_clusters;
//void WriteSecondSeekHead();
void WriteCues();
//void FinalClusters(__int64 pos);
//bool ReadyToCreateNewClusterVideo(const StreamVideo::VideoFrame&) const;
void CreateNewCluster(const StreamVideo::VideoFrame*);
void CreateNewClusterAudioOnly();
void WriteVideoFrame(
Cluster&,
ULONG&,
const StreamVideo::VideoFrame* stop,
const StreamVideo::VideoFrame* next,
LONG prev_timecode);
void WriteAudioFrame(Cluster&, ULONG&);
void WriteCuePoints(const Cluster&);
void WriteCuePoint(const Cluster&, const Keyframe&);
//EOS can happen either because we receive a notification from the stream,
//or because the graph was stopped (before reaching end-of-stream proper).
//The following flags are use to keep track of whether we've seen
//EOS already.
bool m_bEOSVideo;
bool m_bEOSAudio;
int m_cEOS;
int EOS(Stream*);
bool m_bLiveMux;
struct BufferedElementSizeInfo
{
unsigned __int64 offset; // offset to size value in |m_buf|
int byte_count; // num bytes for storage of size value
int num_bytes_to_ignore; // num bytes to ignore in buffer (ID size +
// |byte_count|)
};
bool m_bBufferData;
BufferedElementSizeInfo m_buf_element_info;
void ResetBuffer();
};
} //end namespace WebmMuxLib