4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "packagingengine.h"
30 #include <theora/theora.h>
31 #include <vorbis/codec.h>
32 #include <vorbis/vorbisenc.h>
37 /* This code was aspired by ffmpeg2theora */
38 /* Special thanks for help on this code goes out to j@v2v.cc */
43 off_t file_bufpos; // position of the start of the buffer inside the file
44 off_t file_pagepos; // position of the page that will be next read
45 off_t file_pagepos_found; // position of last page that was returned (in seeking operations)
56 ogg_int64_t audio_bytesout;
57 ogg_int64_t video_bytesout;
59 ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
60 ogg_packet op; /* one raw packet of data for decode */
66 vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
67 vorbis_comment vc; /* struct that stores all the user comments */
68 vorbis_dsp_state vd; /* central working state for the packet<->PCM encoder/decoder */
69 vorbis_block vb; /* local working space for packet<->PCM encode/decode */
72 ogg_stream_state to; /* take physical pages, weld into a logical
73 * stream of packets */
74 ogg_stream_state vo; /* take physical pages, weld into a logical
75 * stream of packets */
83 int vpage_buffer_length;
84 int apage_buffer_length;
87 // stuff needed for reading only
88 sync_window_t *audiosync;
89 sync_window_t *videosync;
91 //to do some manual page flusing
98 class FileOGG : public FileBase
100 friend class PackagingEngineOGG;
102 FileOGG(Asset *asset, File *file);
105 static void get_parameters(BC_WindowBase *parent_window,
106 Asset *asset, BC_WindowBase* &format_window,
107 int audio_options, int video_options, EDL *edl);
109 int reset_parameters_derived();
110 int open_file(int rd, int wr);
111 static int check_sig(Asset *asset);
113 int close_file_derived();
114 int64_t get_video_position();
115 int64_t get_audio_position();
116 int set_video_position(int64_t x);
117 int set_audio_position(int64_t x);
118 int colormodel_supported(int colormodel);
119 int get_best_colormodel(Asset *asset, int driver);
120 int write_samples(double **buffer, int64_t len);
121 int write_frames(VFrame ***frames, int len);
122 int read_samples(double *buffer, int64_t len);
123 int read_frame(VFrame *frame);
126 int write_samples_vorbis(double **buffer, int64_t len, int e_o_s);
127 int write_frames_theora(VFrame ***frames, int len, int e_o_s);
128 void flush_ogg(int e_o_s);
129 int write_audio_page();
130 int write_video_page();
135 theoraframes_info_t *tf;
139 off_t filedata_begin;
141 int ogg_get_last_page(sync_window_t *sw, long serialno, ogg_page *og);
142 int ogg_get_prev_page(sync_window_t *sw, long serialno, ogg_page *og);
143 int ogg_get_first_page(sync_window_t *sw, long serialno, ogg_page *og);
144 int ogg_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
145 int ogg_sync_and_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
147 int ogg_get_page_of_sample(sync_window_t *sw, long serialno, ogg_page *og, int64_t sample);
148 int ogg_seek_to_sample(sync_window_t *sw, long serialno, int64_t sample);
149 int ogg_decode_more_samples(sync_window_t *sw, long serialno);
151 int ogg_get_page_of_frame(sync_window_t *sw, long serialno, ogg_page *og, int64_t frame);
152 int ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *position);
153 int ogg_seek_to_databegin(sync_window_t *sw, long serialno);
156 int64_t start_sample; // first and last sample inside this file
158 int64_t start_frame; // first and last frame inside this file
162 int64_t ogg_sample_position; // what will be the next sample taken from vorbis decoder
163 int64_t next_sample_position; // what is the next sample read_samples must deliver
165 int move_history(int from, int to, int len);
169 #define HISTORY_MAX 0x100000
171 int64_t history_start;
172 int64_t history_size;
175 int64_t ogg_frame_position; // LAST decoded frame position
176 int64_t next_frame_position; // what is the next sample read_frames must deliver
177 char theora_keyframe_granule_shift;
181 class OGGConfigAudio;
182 class OGGConfigVideo;
184 class OGGVorbisFixedBitrate : public BC_Radial
187 OGGVorbisFixedBitrate(int x, int y, OGGConfigAudio *gui);
192 class OGGVorbisVariableBitrate : public BC_Radial
195 OGGVorbisVariableBitrate(int x, int y, OGGConfigAudio *gui);
200 class OGGVorbisMinBitrate : public BC_TextBox
203 OGGVorbisMinBitrate(int x,
211 class OGGVorbisMaxBitrate : public BC_TextBox
214 OGGVorbisMaxBitrate(int x,
222 class OGGVorbisAvgBitrate : public BC_TextBox
225 OGGVorbisAvgBitrate(int x,
234 class OGGConfigAudio: public BC_Window
237 OGGConfigAudio(BC_WindowBase *parent_window, Asset *asset);
240 void create_objects();
244 OGGVorbisFixedBitrate *fixed_bitrate;
245 OGGVorbisVariableBitrate *variable_bitrate;
247 BC_WindowBase *parent_window;
248 char string[BCTEXTLEN];
252 class OGGTheoraBitrate : public BC_TextBox
255 OGGTheoraBitrate(int x, int y, OGGConfigVideo *gui);
260 class OGGTheoraKeyframeFrequency : public BC_TumbleTextBox
263 OGGTheoraKeyframeFrequency(int x, int y, OGGConfigVideo *gui);
268 class OGGTheoraKeyframeForceFrequency : public BC_TumbleTextBox
271 OGGTheoraKeyframeForceFrequency(int x, int y, OGGConfigVideo *gui);
276 class OGGTheoraSharpness : public BC_TumbleTextBox
279 OGGTheoraSharpness(int x, int y, OGGConfigVideo *gui);
284 class OGGTheoraFixedBitrate : public BC_Radial
287 OGGTheoraFixedBitrate(int x, int y, OGGConfigVideo *gui);
292 class OGGTheoraFixedQuality : public BC_Radial
295 OGGTheoraFixedQuality(int x, int y, OGGConfigVideo *gui);
302 class OGGConfigVideo: public BC_Window
305 OGGConfigVideo(BC_WindowBase *parent_window, Asset *asset);
308 void create_objects();
311 OGGTheoraFixedBitrate *fixed_bitrate;
312 OGGTheoraFixedQuality *fixed_quality;
315 BC_WindowBase *parent_window;
318 class PackagingEngineOGG : public PackagingEngine
321 PackagingEngineOGG();
322 ~PackagingEngineOGG();
323 int create_packages_single_farm(
325 Preferences *preferences,
326 Asset *default_asset,
329 RenderPackage* get_package_single_farm(double frames_per_second,
332 int64_t get_progress_max();
333 void get_package_paths(ArrayList<char*> *path_list);
334 int packages_are_done();
339 RenderPackage **packages;
341 double video_package_len; // Target length of a single package
343 Asset *default_asset;
344 Preferences *preferences;
348 int64_t audio_position;
349 int64_t video_position;