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
25 #include "../config.h"
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,
107 BC_WindowBase* &format_window,
111 int reset_parameters_derived();
112 int open_file(int rd, int wr);
113 static int check_sig(Asset *asset);
115 int close_file_derived();
116 int64_t get_video_position();
117 int64_t get_audio_position();
118 int set_video_position(int64_t x);
119 int set_audio_position(int64_t x);
120 int colormodel_supported(int colormodel);
121 int get_best_colormodel(Asset *asset, int driver);
122 int write_samples(double **buffer, int64_t len);
123 int write_frames(VFrame ***frames, int len);
124 int read_samples(double *buffer, int64_t len);
125 int read_frame(VFrame *frame);
128 int write_samples_vorbis(double **buffer, int64_t len, int e_o_s);
129 int write_frames_theora(VFrame ***frames, int len, int e_o_s);
130 void flush_ogg(int e_o_s);
131 int write_audio_page();
132 int write_video_page();
137 theoraframes_info_t *tf;
141 off_t filedata_begin;
143 int ogg_get_last_page(sync_window_t *sw, long serialno, ogg_page *og);
144 int ogg_get_prev_page(sync_window_t *sw, long serialno, ogg_page *og);
145 int ogg_get_first_page(sync_window_t *sw, long serialno, ogg_page *og);
146 int ogg_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
147 int ogg_sync_and_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
149 int ogg_get_page_of_sample(sync_window_t *sw, long serialno, ogg_page *og, int64_t sample);
150 int ogg_seek_to_sample(sync_window_t *sw, long serialno, int64_t sample);
151 int ogg_decode_more_samples(sync_window_t *sw, long serialno);
153 int ogg_get_page_of_frame(sync_window_t *sw, long serialno, ogg_page *og, int64_t frame);
154 int ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *position);
155 int ogg_seek_to_databegin(sync_window_t *sw, long serialno);
158 int64_t start_sample; // first and last sample inside this file
160 int64_t start_frame; // first and last frame inside this file
164 int64_t ogg_sample_position; // what will be the next sample taken from vorbis decoder
165 int64_t next_sample_position; // what is the next sample read_samples must deliver
167 int move_history(int from, int to, int len);
171 #define HISTORY_MAX 0x100000
173 int64_t history_start;
174 int64_t history_size;
177 int64_t ogg_frame_position; // LAST decoded frame position
178 int64_t next_frame_position; // what is the next sample read_frames must deliver
179 char theora_keyframe_granule_shift;
183 class OGGConfigAudio;
184 class OGGConfigVideo;
186 class OGGVorbisFixedBitrate : public BC_Radial
189 OGGVorbisFixedBitrate(int x, int y, OGGConfigAudio *gui);
194 class OGGVorbisVariableBitrate : public BC_Radial
197 OGGVorbisVariableBitrate(int x, int y, OGGConfigAudio *gui);
202 class OGGVorbisMinBitrate : public BC_TextBox
205 OGGVorbisMinBitrate(int x,
213 class OGGVorbisMaxBitrate : public BC_TextBox
216 OGGVorbisMaxBitrate(int x,
224 class OGGVorbisAvgBitrate : public BC_TextBox
227 OGGVorbisAvgBitrate(int x,
236 class OGGConfigAudio: public BC_Window
239 OGGConfigAudio(BC_WindowBase *parent_window, Asset *asset);
242 void create_objects();
246 OGGVorbisFixedBitrate *fixed_bitrate;
247 OGGVorbisVariableBitrate *variable_bitrate;
249 BC_WindowBase *parent_window;
250 char string[BCTEXTLEN];
254 class OGGTheoraBitrate : public BC_TextBox
257 OGGTheoraBitrate(int x, int y, OGGConfigVideo *gui);
262 class OGGTheoraKeyframeFrequency : public BC_TumbleTextBox
265 OGGTheoraKeyframeFrequency(int x, int y, OGGConfigVideo *gui);
270 class OGGTheoraKeyframeForceFrequency : public BC_TumbleTextBox
273 OGGTheoraKeyframeForceFrequency(int x, int y, OGGConfigVideo *gui);
278 class OGGTheoraSharpness : public BC_TumbleTextBox
281 OGGTheoraSharpness(int x, int y, OGGConfigVideo *gui);
286 class OGGTheoraFixedBitrate : public BC_Radial
289 OGGTheoraFixedBitrate(int x, int y, OGGConfigVideo *gui);
294 class OGGTheoraFixedQuality : public BC_Radial
297 OGGTheoraFixedQuality(int x, int y, OGGConfigVideo *gui);
304 class OGGConfigVideo: public BC_Window
307 OGGConfigVideo(BC_WindowBase *parent_window, Asset *asset);
310 void create_objects();
313 OGGTheoraFixedBitrate *fixed_bitrate;
314 OGGTheoraFixedQuality *fixed_quality;
317 BC_WindowBase *parent_window;
320 class PackagingEngineOGG : public PackagingEngine
323 PackagingEngineOGG();
324 ~PackagingEngineOGG();
325 int create_packages_single_farm(
327 Preferences *preferences,
328 Asset *default_asset,
331 RenderPackage* get_package_single_farm(double frames_per_second,
334 int64_t get_progress_max();
335 void get_package_paths(ArrayList<char*> *path_list);
336 int packages_are_done();
341 RenderPackage **packages;
343 double video_package_len; // Target length of a single package
345 Asset *default_asset;
346 Preferences *preferences;
350 int64_t audio_position;
351 int64_t video_position;