2
|
1 #include <oggplayer.h>
|
|
2 #include "SDL_audiocvt.hpp"
|
|
3 #include <fstream>
|
|
4 #include <vector>
|
|
5 #include <theora/theora.h>
|
|
6 #include <vorbis/codec.h>
|
|
7 #include <boost/thread.hpp>
|
|
8 #include <boost/bind.hpp>
|
|
9 #include <boost/thread/mutex.hpp>
|
|
10 #include <boost/thread/locks.hpp>
|
|
11 #include <boost/thread/condition.hpp>
|
|
12 #include <boost/circular_buffer.hpp>
|
|
13 #include <boost/timer.hpp>
|
|
14
|
|
15 struct OggPlayer::Imp {
|
|
16
|
|
17 Imp() :
|
|
18 cirbuf(0),video_lock(video_mut, boost::defer_lock){
|
|
19 failbit = false;
|
|
20 playing = false;
|
|
21 need_close = false;
|
|
22 time_factor = 1;
|
|
23 refs = 1;
|
|
24 }
|
|
25
|
|
26 ~Imp() {
|
|
27 // open() tears down the partial setup on fail
|
|
28 if (!failbit)
|
|
29 close();
|
|
30 }
|
|
31 int queue_page(ogg_page * page);
|
|
32 bool buffer_data();
|
|
33 double get_time();
|
|
34 void close();
|
|
35 bool init_decoders();
|
|
36 bool parse_headers();
|
|
37 void open(std::string path, AudioFormat audio_format, int channels,
|
|
38 int rate, VideoFormat video_format);
|
|
39 bool decode_audio();
|
|
40 bool decode_video();
|
|
41 bool ready();
|
|
42 void play();
|
|
43 void play_loop();
|
|
44
|
|
45 bool failbit;
|
|
46 std::ifstream file_in;
|
|
47
|
|
48 int theora_p;
|
|
49 int vorbis_p;
|
|
50
|
|
51 ogg_sync_state o_sync;
|
|
52
|
|
53 vorbis_comment v_comment;
|
|
54 theora_info t_info;
|
|
55 theora_comment t_comment;
|
|
56 vorbis_info v_info;
|
|
57
|
|
58 ogg_page o_page;
|
|
59 ogg_packet o_packet;
|
|
60
|
|
61 ogg_stream_state o_tsstate;
|
|
62 ogg_stream_state o_vsstate;
|
|
63
|
|
64 theora_state t_state;
|
|
65 vorbis_dsp_state v_state;
|
|
66 vorbis_block v_block;
|
|
67
|
|
68 int pp_level_max;
|
|
69 int pp_level;
|
|
70 int pp_inc;
|
|
71
|
|
72 char* audio_buffer;
|
|
73 boost::circular_buffer<char> cirbuf;
|
|
74 unsigned int audio_buffer_size;
|
|
75 SDL_AudioCVT cvt;
|
|
76
|
|
77 bool playing;
|
|
78
|
|
79 boost::thread play_thread;
|
|
80 boost::mutex audio_mut;
|
|
81 boost::mutex video_mut;
|
|
82 boost::condition_variable audio_ready_cond;
|
|
83 boost::condition_variable video_ready_cond;
|
|
84
|
|
85 bool videobuf_ready;
|
|
86 double videobuf_time;
|
|
87
|
|
88 bool audio_cache_ready;
|
|
89
|
|
90 // This lock should only be used from the main thread
|
|
91 boost::unique_lock<boost::mutex> video_lock;
|
|
92 // These variables are used to identify the frames (not just count them, not a debug variable)
|
|
93 // see video_buffer_try_lock and video_read
|
|
94 int frame;
|
|
95 int last_frame_read;
|
|
96
|
|
97 int audio_bytes_played;
|
|
98 struct AudioGranulePos {
|
|
99 int pos;
|
|
100 double set_time;
|
|
101 };
|
|
102 std::deque<AudioGranulePos> audio_granule_poses;
|
|
103 double time_factor;
|
|
104
|
|
105 struct PixelFormat{
|
|
106 void set(int r,int g,int b,int bpp){
|
|
107 r_offset = r;
|
|
108 g_offset = g;
|
|
109 b_offset = b;
|
|
110 this->bpp =bpp;
|
|
111 }
|
|
112 int r_offset;
|
|
113 int g_offset;
|
|
114 int b_offset;
|
|
115 // if bpp=4 we have an alpha channel at offset 4
|
|
116 int bpp;
|
|
117
|
|
118 } pixel_format;
|
|
119 bool need_close;
|
|
120 boost::timer timer;
|
|
121 int refs;
|
|
122 };
|