openMSX
OggReader.hh
Go to the documentation of this file.
1 #ifndef OGGREADER_HH
2 #define OGGREADER_HH
3 
4 #include "File.hh"
5 #include "circular_buffer.hh"
6 #include <ogg/ogg.h>
7 #include <vorbis/codec.h>
8 #include <theora/theoradec.h>
9 #include <memory>
10 #include <list>
11 #include <utility>
12 #include <vector>
13 
14 namespace openmsx {
15 
16 class CliComm;
17 class RawFrame;
18 class Filename;
19 
21 {
22  static const size_t UNKNOWN_POS = size_t(-1);
23  static const unsigned MAX_SAMPLES = 2048;
24  size_t position;
25  unsigned length;
26  float pcm[2][MAX_SAMPLES];
27 };
28 
29 struct Frame
30 {
31  explicit Frame(const th_ycbcr_buffer& yuv);
32  ~Frame();
33 
34  th_ycbcr_buffer buffer;
35  size_t no;
36  int length;
37 };
38 
39 class OggReader
40 {
41 public:
42  OggReader(const OggReader&) = delete;
43  OggReader& operator=(const OggReader&) = delete;
44 
45  OggReader(const Filename& filename, CliComm& cli);
46  ~OggReader();
47 
48  bool seek(size_t frame, size_t sample);
49  unsigned getSampleRate() const { return vi.rate; }
50  void getFrameNo(RawFrame& frame, size_t frameno);
51  const AudioFragment* getAudio(size_t sample);
52  size_t getFrames() const { return totalFrames; }
53  int getFrameRate() const { return frameRate; }
54 
55  // metadata
56  bool stopFrame(size_t frame) const;
57  size_t getChapter(int chapterNo) const;
58 
59 private:
60  void cleanup();
61  void readTheora(ogg_packet* packet);
62  void theoraHeaderPage(ogg_page* page, th_info& ti, th_comment& tc,
63  th_setup_info*& tsi);
64  void readMetadata(th_comment& tc);
65  void readVorbis(ogg_packet* packet);
66  void vorbisHeaderPage(ogg_page* page);
67  bool nextPage(ogg_page* page);
68  bool nextPacket();
69  void recycleAudio(std::unique_ptr<AudioFragment> audio);
70  void vorbisFoundPosition();
71  size_t frameNo(ogg_packet* packet);
72 
73  size_t findOffset(size_t frame, size_t sample);
74  size_t bisection(size_t frame, size_t sample,
75  size_t maxOffset, size_t maxSamples, size_t maxFrames);
76 
77  CliComm& cli;
78  File file;
79 
80  enum State {
81  PLAYING,
82  FIND_LAST,
83  FIND_FIRST,
84  FIND_KEYFRAME
85  } state;
86 
87  // ogg state
88  ogg_sync_state sync;
89  ogg_stream_state vorbisStream, theoraStream;
90  int audioSerial;
91  int videoSerial;
92  int skeletonSerial;
93  size_t fileOffset;
94  size_t fileSize;
95 
96  // video
97  th_dec_ctx* theora;
98  int frameRate;
99  size_t keyFrame;
100  size_t currentFrame;
101  int granuleShift;
102  size_t totalFrames;
103 
105  std::vector<std::unique_ptr<Frame>> recycleFrameList;
106 
107  // audio
108  int audioHeaders;
109  vorbis_info vi;
110  vorbis_comment vc;
111  vorbis_dsp_state vd;
112  vorbis_block vb;
113  size_t currentSample;
114  size_t vorbisPos;
115 
116  std::list<std::unique_ptr<AudioFragment>> audioList;
117  cb_queue<std::unique_ptr<AudioFragment>> recycleAudioList;
118 
119  // Metadata
120  std::vector<size_t> stopFrames;
121  std::vector<std::pair<int, size_t>> chapters;
122 };
123 
124 } // namespace openmsx
125 
126 #endif
size_t getFrames() const
Definition: OggReader.hh:52
This implements a queue on top of circular_buffer (not part of boost).
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
Definition: RawFrame.hh:25
static const unsigned MAX_SAMPLES
Definition: OggReader.hh:23
float pcm[2][MAX_SAMPLES]
Definition: OggReader.hh:26
th_ycbcr_buffer buffer
Definition: OggReader.hh:34
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
static const size_t UNKNOWN_POS
Definition: OggReader.hh:22
unsigned getSampleRate() const
Definition: OggReader.hh:49
int getFrameRate() const
Definition: OggReader.hh:53