#ifndef FILEOGG_H
#define FILEOGG_H
+#ifdef HAVE_OGG
#include "edl.inc"
#include "filebase.h"
#include "file.inc"
-#include "packagingengine.h"
+#include "mutex.inc"
#include <theora/theora.h>
+#include <theora/theoraenc.h>
+#include <theora/theoradec.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisenc.h>
-#include <libdv/dv.h>
-
/* This code was aspired by ffmpeg2theora */
/* Special thanks for help on this code goes out to j@v2v.cc */
-typedef struct
-{
- ogg_sync_state sync;
- off_t file_bufpos; // position of the start of the buffer inside the file
- off_t file_pagepos; // position of the page that will be next read
- off_t file_pagepos_found; // position of last page that was returned (in seeking operations)
- int wlen;
-} sync_window_t;
-
-typedef struct
-{
- ogg_page audiopage;
- ogg_page videopage;
-
- double audiotime;
- double videotime;
- ogg_int64_t audio_bytesout;
- ogg_int64_t video_bytesout;
-
- ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
- ogg_packet op; /* one raw packet of data for decode */
-
- theora_info ti;
- theora_comment tc;
- theora_state td;
-
- vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
- vorbis_comment vc; /* struct that stores all the user comments */
- vorbis_dsp_state vd; /* central working state for the packet<->PCM encoder/decoder */
- vorbis_block vb; /* local working space for packet<->PCM encode/decode */
-
- /* used for muxing */
- ogg_stream_state to; /* take physical pages, weld into a logical
- * stream of packets */
- ogg_stream_state vo; /* take physical pages, weld into a logical
- * stream of packets */
-
- int apage_valid;
- int vpage_valid;
- unsigned char *apage;
- unsigned char *vpage;
- int vpage_len;
- int apage_len;
- int vpage_buffer_length;
- int apage_buffer_length;
-
-
-// stuff needed for reading only
- sync_window_t *audiosync;
- sync_window_t *videosync;
+#define mn_pagesz 32
- //to do some manual page flusing
- int v_pkg;
- int a_pkg;
+class sync_window_t : public ogg_sync_state
+{
+public:
+ sync_window_t(FILE *fp, Mutex *sync_lock, int64_t begin=0, int64_t end=0);
+ ~sync_window_t();
+ int ogg_read_locked(int buflen);
+ int ogg_read_buffer(int buflen);
+ int ogg_read_buffer_at(off_t filepos, int buflen);
+ int ogg_sync_and_take_page_out(ogg_page *og);
+ int ogg_take_page_out_autoadvance(ogg_page *og);
+ int ogg_sync_and_get_next_page(long serialno, ogg_page *og);
+ int ogg_prev_page_search(long serialno,ogg_page *og,
+ off_t begin, off_t end);
+ int ogg_get_prev_page(long serialno, ogg_page *og);
+ int ogg_get_next_page(long serialno, ogg_page *og);
+ int ogg_get_first_page(long serialno, ogg_page *og);
+ int ogg_get_last_page(long serialno, ogg_page *og);
+
+ int64_t filepos; // current file position
+ int64_t bufpos; // position at start of read
+ int64_t pagpos; // last search target position
+ FILE *fp;
+ Mutex *sync_lock;
+ int64_t file_begin, file_end;
+};
-}
-theoraframes_info_t;
+class OGG_PageBfr
+{
+public:
+ int allocated, len;
+ int valid, packets;
+ int64_t position;
+ uint8_t *page;
+
+ OGG_PageBfr();
+ ~OGG_PageBfr();
+ void demand(int sz);
+ int write_page(FILE *fp);
+ int64_t load(ogg_page *og);
+};
class FileOGG : public FileBase
{
-friend class PackagingEngineOGG;
public:
FileOGG(Asset *asset, File *file);
~FileOGG();
static void get_parameters(BC_WindowBase *parent_window,
- Asset *asset, BC_WindowBase* &format_window,
- int audio_options, int video_options, EDL *edl);
-
- int reset_parameters_derived();
- int open_file(int rd, int wr);
+ Asset *asset, BC_WindowBase *&format_window,
+ int audio_options,int video_options,EDL *edl);
static int check_sig(Asset *asset);
+ int open_file(int rd,int wr);
int close_file();
- int close_file_derived();
+
int64_t get_video_position();
int64_t get_audio_position();
- int set_video_position(int64_t x);
- int set_audio_position(int64_t x);
+ int set_video_position(int64_t pos);
int colormodel_supported(int colormodel);
- int get_best_colormodel(Asset *asset, int driver);
- int write_samples(double **buffer, int64_t len);
- int write_frames(VFrame ***frames, int len);
- int read_samples(double *buffer, int64_t len);
+ int get_best_colormodel(Asset *asset,int driver);
int read_frame(VFrame *frame);
+ int set_audio_position(int64_t pos);
+ int read_samples(double *buffer,int64_t len);
+ int write_samples(double **buffer,int64_t len);
+ int write_frames(VFrame ***frames,int len);
private:
+ void init();
+ int encode_theora_init();
+ int encode_vorbis_init();
+ int ogg_init_encode(FILE *out);
+ void close_encoder();
+ int decode_theora_init();
+ int decode_vorbis_init();
+ int ogg_init_decode(FILE *inp);
+ void close_decoder();
+
int write_samples_vorbis(double **buffer, int64_t len, int e_o_s);
int write_frames_theora(VFrame ***frames, int len, int e_o_s);
void flush_ogg(int e_o_s);
int write_audio_page();
int write_video_page();
- FILE *stream;
+ FILE *inp, *out;
off_t file_length;
+ int audio, video;
+ int64_t frame_position;
+ int64_t sample_position;
- theoraframes_info_t *tf;
VFrame *temp_frame;
- Mutex *flush_lock;
-
- off_t filedata_begin;
-
- int ogg_get_last_page(sync_window_t *sw, long serialno, ogg_page *og);
- int ogg_get_prev_page(sync_window_t *sw, long serialno, ogg_page *og);
- int ogg_get_first_page(sync_window_t *sw, long serialno, ogg_page *og);
- int ogg_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
- int ogg_sync_and_get_next_page(sync_window_t *sw, long serialno, ogg_page *og);
-
- int ogg_get_page_of_sample(sync_window_t *sw, long serialno, ogg_page *og, int64_t sample);
- int ogg_seek_to_sample(sync_window_t *sw, long serialno, int64_t sample);
- int ogg_decode_more_samples(sync_window_t *sw, long serialno);
-
- int ogg_get_page_of_frame(sync_window_t *sw, long serialno, ogg_page *og, int64_t frame);
- int ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *position);
- int ogg_seek_to_databegin(sync_window_t *sw, long serialno);
-
-
- int64_t start_sample; // first and last sample inside this file
- int64_t last_sample;
- int64_t start_frame; // first and last frame inside this file
- int64_t last_frame;
-
-
- int64_t ogg_sample_position; // what will be the next sample taken from vorbis decoder
- int64_t next_sample_position; // what is the next sample read_samples must deliver
-
- int move_history(int from, int to, int len);
-
+ Mutex *file_lock;
float **pcm_history;
#ifndef HISTORY_MAX
#define HISTORY_MAX 0x100000
#endif
int64_t history_start;
int64_t history_size;
+ int pcm_channels;
+ int ach, ahz; // audio channels, sample rate
+ int amn, amx; // audio min/max bitrate
+ int abr, avbr, aqu; // audio bitrate, variable bitrate, quality
+ int asz, afrmsz; // audio sample size, frame size
+
+ off_t file_begin, file_end;
+ sync_window_t *audiosync;
+ sync_window_t *videosync;
+
+ int64_t ogg_sample_pos(ogg_page *og);
+ int64_t ogg_next_sample_pos(ogg_page *og);
+ int64_t ogg_frame_pos(ogg_page *og);
+ int64_t ogg_next_frame_pos(ogg_page *og);
+ int ogg_read_buffer(FILE *in, sync_window_t *sy, int buflen);
+ int ogg_get_video_packet(ogg_packet *op);
+ int ogg_get_audio_packet(ogg_packet *op);
+
+ int ogg_get_page_of_sample(ogg_page *og, int64_t sample);
+ int ogg_seek_to_sample(int64_t sample);
+ int ogg_decode_more_samples();
+
+ int ogg_get_page_of_frame(ogg_page *og, int64_t frame);
+ int ogg_seek_to_keyframe(int64_t frame, int64_t *keyframe_number);
+ int move_history(int from, int to, int len);
+ ogg_stream_state to; // theora to ogg out
+ ogg_stream_state vo; // vorbis to ogg out
+ int64_t ogg_sample_position, ogg_frame_position;
+ int64_t next_sample_position, next_frame_position;
+ int64_t start_sample, last_sample; // first and last sample inside this file
+ int64_t start_frame, last_frame; // first and last frame inside this file
+ int64_t audio_pos, video_pos; // decoder last sample/frame in
+ int audio_eos, video_eos; // decoder sample/frame end of file
+
+ th_enc_ctx *enc; // theora video encode context
+ th_dec_ctx *dec; // theora video decode context
+ th_info ti; // theora video encoder init parameters
+ th_setup_info *ts; // theora video setup huff/quant codes
+ th_comment tc; // header init parameters
+ vorbis_info vi; // vorbis audio encoder init parameters
+ vorbis_comment vc; // header init parameters
+ vorbis_dsp_state vd; // vorbis decode audio context
+ vorbis_block vb; // vorbis decode buffering
+ int force_keyframes;
+ int vp3_compatible;
+ int soft_target;
+
+ int pic_x, pic_y, pic_w, pic_h;
+ int frame_w, frame_h;
+ int colorspace, pixfmt;
+ int bitrate, quality;
+ int keyframe_period, keyframe_force;
+ int fps_num, fps_den;
+ int aratio_num, aratio_den;
+
+ OGG_PageBfr apage, vpage;
+ double audiotime, videotime;
+ int keyframe_granule_shift;
+ int iframe_granule_offset;
int theora_cmodel;
- int64_t ogg_frame_position; // LAST decoded frame position
- int64_t next_frame_position; // what is the next sample read_frames must deliver
- char theora_keyframe_granule_shift;
- int final_write;
};
class OGGConfigAudio;
BC_WindowBase *parent_window;
};
-class PackagingEngineOGG : public PackagingEngine
-{
-public:
- PackagingEngineOGG();
- ~PackagingEngineOGG();
- int create_packages_single_farm(
- EDL *edl,
- Preferences *preferences,
- Asset *default_asset,
- double total_start,
- double total_end);
- RenderPackage* get_package_single_farm(double frames_per_second,
- int client_number,
- int use_local_rate);
- int64_t get_progress_max();
- void get_package_paths(ArrayList<char*> *path_list);
- int packages_are_done();
-
-private:
- EDL *edl;
-
- RenderPackage **packages;
- int total_packages;
- double video_package_len; // Target length of a single package
-
- Asset *default_asset;
- Preferences *preferences;
- int current_package;
- double total_start;
- double total_end;
- int64_t audio_position;
- int64_t video_position;
- int64_t audio_start;
- int64_t video_start;
- int64_t audio_end;
- int64_t video_end;
-
-};
-
-
+#endif
#endif