DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
cap_ogg.c
Go to the documentation of this file.
1#include <sys/types.h>
2
3#include "quakedef.h"
4#include "client.h"
5#include "cap_ogg.h"
6
7// video capture cvars
8static cvar_t cl_capturevideo_ogg_theora_vp3compat = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_vp3compat", "1", "make VP3 compatible theora streams"};
9static cvar_t cl_capturevideo_ogg_theora_quality = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_quality", "48", "video quality factor (0 to 63), or -1 to use bitrate only; higher is better; setting both to -1 achieves unlimited quality"};
10static cvar_t cl_capturevideo_ogg_theora_bitrate = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_bitrate", "-1", "video bitrate (45 to 2000 kbps), or -1 to use quality only; higher is better; setting both to -1 achieves unlimited quality"};
11static cvar_t cl_capturevideo_ogg_theora_keyframe_bitrate_multiplier = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_keyframe_bitrate_multiplier", "1.5", "how much more bit rate to use for keyframes, specified as a factor of at least 1"};
12static cvar_t cl_capturevideo_ogg_theora_keyframe_maxinterval = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_keyframe_maxinterval", "64", "maximum keyframe interval (1 to 1000)"};
13static cvar_t cl_capturevideo_ogg_theora_keyframe_mininterval = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_keyframe_mininterval", "8", "minimum keyframe interval (1 to 1000)"};
14static cvar_t cl_capturevideo_ogg_theora_keyframe_auto_threshold = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_keyframe_auto_threshold", "80", "threshold for key frame decision (0 to 100)"};
15static cvar_t cl_capturevideo_ogg_theora_noise_sensitivity = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_noise_sensitivity", "1", "video noise sensitivity (0 to 6); lower is better"};
16static cvar_t cl_capturevideo_ogg_theora_sharpness = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_theora_sharpness", "0", "sharpness (0 to 2); lower is sharper"};
17static cvar_t cl_capturevideo_ogg_vorbis_quality = {CF_CLIENT | CF_ARCHIVE, "cl_capturevideo_ogg_vorbis_quality", "3", "audio quality (-1 to 10); higher is better"};
18
19typedef struct {
20 long endbyte;
21 int endbit;
22
23 unsigned char *buffer;
24 unsigned char *ptr;
25 long storage;
27
28/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
29
30typedef struct {
31 unsigned char *header;
33 unsigned char *body;
35} ogg_page;
36
37/* ogg_stream_state contains the current encode/decode state of a logical
38 Ogg bitstream **********************************************************/
39
40typedef struct {
41 unsigned char *body_data; /* bytes from packet bodies */
42 long body_storage; /* storage elements allocated */
43 long body_fill; /* elements stored; fill mark */
44 long body_returned; /* elements of fill returned */
45
46
47 int *lacing_vals; /* The values that will go to the segment table */
48 int64_t *granule_vals; /* granulepos values for headers. Not compact
49 this way, but it is simple coupled to the
50 lacing fifo */
55
56 unsigned char header[282]; /* working space for header encode */
58
59 int e_o_s; /* set when we have buffered the last packet in the
60 logical bitstream */
61 int b_o_s; /* set after we've written the initial page
62 of a logical bitstream */
64 long pageno;
65 int64_t packetno; /* sequence number for decode; the framing
66 knows where there's a hole in the data,
67 but we need coupling so that the codec
68 (which is in a seperate abstraction
69 layer) also knows about the gap */
70 int64_t granulepos;
71
73
74/* ogg_packet is used to encapsulate the data and metadata belonging
75 to a single raw Ogg/Vorbis packet *************************************/
76
77typedef struct {
78 unsigned char *packet;
79 long bytes;
80 long b_o_s;
81 long e_o_s;
82
83 int64_t granulepos;
84
85 int64_t packetno; /* sequence number for decode; the framing
86 knows where there's a hole in the data,
87 but we need coupling so that the codec
88 (which is in a seperate abstraction
89 layer) also knows about the gap */
91
92typedef struct {
93 unsigned char *data;
95 int fill;
97
102
103/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
104
108
109/* Ogg BITSTREAM PRIMITIVES: general ***************************/
110
111static int (*qogg_stream_init) (ogg_stream_state *os,int serialno);
113static int64_t (*qogg_page_granulepos) (ogg_page *og);
114
115// end of ogg.h stuff
116
117// vorbis/codec.h stuff
118typedef struct vorbis_info{
121 long rate;
122
123 /* The below bitrate declarations are *hints*.
124 Combinations of the three values carry the following implications:
125
126 all three set to the same value:
127 implies a fixed rate bitstream
128 only nominal set:
129 implies a VBR stream that averages the nominal bitrate. No hard
130 upper/lower limit
131 upper and or lower set:
132 implies a VBR bitstream that obeys the bitrate limits. nominal
133 may also be set to give a nominal rate.
134 none set:
135 the coder does not care to speculate.
136 */
137
142
145
146/* vorbis_dsp_state buffers the current vorbis audio
147 analysis/synthesis state. The DSP state belongs to a specific
148 logical bitstream ****************************************************/
149typedef struct vorbis_dsp_state{
152
153 float **pcm;
154 float **pcmret;
158
161
162 long lW;
163 long W;
164 long nW;
166
167 int64_t granulepos;
168 int64_t sequence;
169
170 int64_t glue_bits;
171 int64_t time_bits;
172 int64_t floor_bits;
173 int64_t res_bits;
174
177
178typedef struct vorbis_block{
179 /* necessary stream state for linking to the framing abstraction */
180 float **pcm; /* this is a pointer into local storage */
182
183 long lW;
184 long W;
185 long nW;
187 int mode;
188
190 int64_t granulepos;
191 int64_t sequence;
192 vorbis_dsp_state *vd; /* For read-only access of configuration */
193
194 /* local storage to avoid remallocing; it's up to the mapping to
195 structure it */
201
202 /* bitmetrics for the frame */
207
208 void *internal;
209
211
212/* vorbis_block is a single block of data to be processed as part of
213the analysis/synthesis stream; it belongs to a specific logical
214bitstream, but is independant from other vorbis_blocks belonging to
215that logical bitstream. *************************************************/
216
218 void *ptr;
220};
221
222/* vorbis_info contains all the setup information specific to the
223 specific compression/decompression mode in progress (eg,
224 psychoacoustic settings, channel setup, options, codebook
225 etc). vorbis_info and substructures are in backends.h.
226*********************************************************************/
227
228/* the comments are not part of vorbis_info so that vorbis_info can be
229 static storage */
230typedef struct vorbis_comment{
231 /* unlimited user comment fields. libvorbis writes 'libvorbis'
232 whatever vendor is set to in encode */
236 char *vendor;
237
239
240
241/* libvorbis encodes in two abstraction layers; first we perform DSP
242 and produce a packet (see docs/analysis.txt). The packet is then
243 coded into a framed OggSquish bitstream by the second layer (see
244 docs/framing.txt). Decode is the reverse process; we sync/frame
245 the bitstream and extract individual packets, then decode the
246 packet back into PCM audio.
247
248 The extra framing/packetizing is used in streaming formats, such as
249 files. Over the net (such as with UDP), the framing and
250 packetization aren't necessary as they're provided by the transport
251 and the streaming layer is not used */
252
253/* Vorbis PRIMITIVES: general ***************************************/
254
259
264 int64_t granulepos);
265
266/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
267
271 vorbis_comment *vc,
272 ogg_packet *op,
273 ogg_packet *op_comm,
274 ogg_packet *op_code);
275static float ** (*qvorbis_analysis_buffer) (vorbis_dsp_state *v,int vals);
279
282 ogg_packet *op);
283
284// end of vorbis/codec.h stuff
285
286// vorbisenc.h stuff
288 long channels,
289 long rate,
290
291 float base_quality /* quality level from 0. (lo) to 1. (hi) */
292 );
293// end of vorbisenc.h stuff
294
295// theora.h stuff
296
297#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
298
299typedef struct {
307 unsigned char *y;
308 unsigned char *u;
309 unsigned char *v;
311} yuv_buffer;
312
322
357typedef struct {
358 uint32_t width;
359 uint32_t height;
360 uint32_t frame_width;
361 uint32_t frame_height;
362 uint32_t offset_x;
363 uint32_t offset_y;
364 uint32_t fps_numerator;
373 /* decode only */
374 unsigned char version_major;
375 unsigned char version_minor;
376 unsigned char version_subminor;
377
379
380 /* encode only */
384 uint32_t keyframe_frequency_force; /* also used for decode init to
385 get granpos shift correct */
390 int32_t sharpness;
391
395
398typedef struct{
400 int64_t granulepos;
401
404
406
435static int (*qtheora_encode_packetout) ( theora_state *t, int last_p,
436 ogg_packet *op);
445static double (*qtheora_granule_time) (theora_state *th,int64_t granulepos);
446static int (*qtheora_control) (theora_state *th,int req,void *buf,size_t buf_sz);
447// end of theora.h stuff
448
450{
451 {"ogg_stream_packetin", (void **) &qogg_stream_packetin},
452 {"ogg_stream_pageout", (void **) &qogg_stream_pageout},
453 {"ogg_stream_flush", (void **) &qogg_stream_flush},
454 {"ogg_stream_init", (void **) &qogg_stream_init},
455 {"ogg_stream_clear", (void **) &qogg_stream_clear},
456 {"ogg_page_granulepos", (void **) &qogg_page_granulepos},
457 {NULL, NULL}
458};
459
461{
462 {"vorbis_encode_init_vbr", (void **) &qvorbis_encode_init_vbr},
463 {NULL, NULL}
464};
465
467{
468 {"vorbis_info_init", (void **) &qvorbis_info_init},
469 {"vorbis_info_clear", (void **) &qvorbis_info_clear},
470 {"vorbis_comment_init", (void **) &qvorbis_comment_init},
471 {"vorbis_comment_clear", (void **) &qvorbis_comment_clear},
472 {"vorbis_block_init", (void **) &qvorbis_block_init},
473 {"vorbis_block_clear", (void **) &qvorbis_block_clear},
474 {"vorbis_dsp_clear", (void **) &qvorbis_dsp_clear},
475 {"vorbis_analysis_init", (void **) &qvorbis_analysis_init},
476 {"vorbis_commentheader_out", (void **) &qvorbis_commentheader_out},
477 {"vorbis_analysis_headerout", (void **) &qvorbis_analysis_headerout},
478 {"vorbis_analysis_buffer", (void **) &qvorbis_analysis_buffer},
479 {"vorbis_analysis_wrote", (void **) &qvorbis_analysis_wrote},
480 {"vorbis_analysis_blockout", (void **) &qvorbis_analysis_blockout},
481 {"vorbis_analysis", (void **) &qvorbis_analysis},
482 {"vorbis_bitrate_addblock", (void **) &qvorbis_bitrate_addblock},
483 {"vorbis_bitrate_flushpacket", (void **) &qvorbis_bitrate_flushpacket},
484 {"vorbis_granule_time", (void **) &qvorbis_granule_time},
485 {NULL, NULL}
486};
487
489{
490 {"theora_info_init", (void **) &qtheora_info_init},
491 {"theora_info_clear", (void **) &qtheora_info_clear},
492 {"theora_comment_init", (void **) &qtheora_comment_init},
493 {"theora_comment_clear", (void **) &qtheora_comment_clear},
494 {"theora_encode_init", (void **) &qtheora_encode_init},
495 {"theora_encode_YUVin", (void **) &qtheora_encode_YUVin},
496 {"theora_encode_packetout", (void **) &qtheora_encode_packetout},
497 {"theora_encode_header", (void **) &qtheora_encode_header},
498 {"theora_encode_comment", (void **) &qtheora_encode_comment},
499 {"theora_encode_tables", (void **) &qtheora_encode_tables},
500 {"theora_clear", (void **) &qtheora_clear},
501 {"theora_granule_time", (void **) &qtheora_granule_time},
502 {"theora_control", (void **) &qtheora_control},
503 {NULL, NULL}
504};
505
507
509{
510 const char* dllnames_og [] =
511 {
512#if defined(WIN32)
513 "libogg-0.dll",
514 "libogg.dll",
515 "ogg.dll",
516#elif defined(MACOSX)
517 "libogg.dylib",
518#else
519 "libogg.so.0",
520 "libogg.so",
521#endif
522 NULL
523 };
524 const char* dllnames_vo [] =
525 {
526#if defined(WIN32)
527 "libvorbis-0.dll",
528 "libvorbis.dll",
529 "vorbis.dll",
530#elif defined(MACOSX)
531 "libvorbis.dylib",
532#else
533 "libvorbis.so.0",
534 "libvorbis.so",
535#endif
536 NULL
537 };
538 const char* dllnames_ve [] =
539 {
540#if defined(WIN32)
541 "libvorbisenc-2.dll",
542 "libvorbisenc.dll",
543 "vorbisenc.dll",
544#elif defined(MACOSX)
545 "libvorbisenc.dylib",
546#else
547 "libvorbisenc.so.2",
548 "libvorbisenc.so",
549#endif
550 NULL
551 };
552 const char* dllnames_th [] =
553 {
554#if defined(WIN32)
555 "libtheora-0.dll",
556 "libtheora.dll",
557 "theora.dll",
558#elif defined(MACOSX)
559 "libtheora.dylib",
560#else
561 "libtheora.so.0",
562 "libtheora.so",
563#endif
564 NULL
565 };
566
567 return
568 Sys_LoadDependency (dllnames_og, &og_dll, oggfuncs)
569 &&
570 Sys_LoadDependency (dllnames_th, &th_dll, theorafuncs)
571 &&
572 Sys_LoadDependency (dllnames_vo, &vo_dll, vorbisfuncs)
573 &&
575}
576
592
594{
595 return og_dll && th_dll && vo_dll && ve_dll;
596}
597
605
606// this struct should not be needed
607// however, libogg appears to pull the ogg_page's data element away from our
608// feet before we get to write the data due to interleaving
609// so this struct is used to keep the page data around until it actually gets
610// written
611typedef struct allocatedoggpage_s
612{
613 size_t len;
614 double time;
615 unsigned char data[65307];
616 // this number is from RFC 3533. In case libogg writes more, we'll have to increase this
617 // but we'll get a Host_Error in this case so we can track it down
618}
620
621typedef struct capturevideostate_ogg_formatspecific_s
622{
624 int serial1, serial2;
630 int yuvi;
633
635}
637#define LOAD_FORMATSPECIFIC_OGG() capturevideostate_ogg_formatspecific_t *format = (capturevideostate_ogg_formatspecific_t *) cls.capturevideo.formatspecific
638
640{
642 ogg_page pg;
643
644 if(!cls.capturevideo.soundrate)
645 {
646 while(qogg_stream_pageout(&format->to, &pg) > 0)
647 {
648 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
649 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
650 }
651 return;
652 }
653
654 for(;;)
655 {
656 // first: make sure we have a page of both types
657 if(!format->videopage.len)
658 if(qogg_stream_pageout(&format->to, &pg) > 0)
659 {
660 format->videopage.len = pg.header_len + pg.body_len;
661 format->videopage.time = qtheora_granule_time(&format->ts, qogg_page_granulepos(&pg));
662 if(format->videopage.len > sizeof(format->videopage.data))
663 Sys_Error("video page too long");
664 memcpy(format->videopage.data, pg.header, pg.header_len);
665 memcpy(format->videopage.data + pg.header_len, pg.body, pg.body_len);
666 }
667 if(!format->audiopage.len)
668 if(qogg_stream_pageout(&format->vo, &pg) > 0)
669 {
670 format->audiopage.len = pg.header_len + pg.body_len;
671 format->audiopage.time = qvorbis_granule_time(&format->vd, qogg_page_granulepos(&pg));
672 if(format->audiopage.len > sizeof(format->audiopage.data))
673 Sys_Error("audio page too long");
674 memcpy(format->audiopage.data, pg.header, pg.header_len);
675 memcpy(format->audiopage.data + pg.header_len, pg.body, pg.body_len);
676 }
677
678 if(format->videopage.len && format->audiopage.len)
679 {
680 // output the page that ends first
681 if(format->videopage.time < format->audiopage.time)
682 {
683 FS_Write(cls.capturevideo.videofile, format->videopage.data, format->videopage.len);
684 format->videopage.len = 0;
685 }
686 else
687 {
688 FS_Write(cls.capturevideo.videofile, format->audiopage.data, format->audiopage.len);
689 format->audiopage.len = 0;
690 }
691 }
692 else
693 break;
694 }
695}
696
698{
700
701 if(cls.capturevideo.soundrate)
702 if(format->audiopage.len)
703 {
704 FS_Write(cls.capturevideo.videofile, format->audiopage.data, format->audiopage.len);
705 format->audiopage.len = 0;
706 }
707
708 if(format->videopage.len)
709 {
710 FS_Write(cls.capturevideo.videofile, format->videopage.data, format->videopage.len);
711 format->videopage.len = 0;
712 }
713}
714
716{
718 ogg_page pg;
719 ogg_packet pt;
720
721 if(format->yuvi >= 0)
722 {
723 // send the previous (and last) frame
724 while(format->lastnum-- > 0)
725 {
726 qtheora_encode_YUVin(&format->ts, &format->yuv[format->yuvi]);
727
728 while(qtheora_encode_packetout(&format->ts, !format->lastnum, &pt))
729 qogg_stream_packetin(&format->to, &pt);
730
732 }
733 }
734
735 if(cls.capturevideo.soundrate)
736 {
738 while(qvorbis_analysis_blockout(&format->vd, &format->vb) == 1)
739 {
742 while(qvorbis_bitrate_flushpacket(&format->vd, &pt))
743 qogg_stream_packetin(&format->vo, &pt);
745 }
746 }
747
749
750 while(qogg_stream_pageout(&format->to, &pg) > 0)
751 {
752 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
753 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
754 }
755
756 if(cls.capturevideo.soundrate)
757 {
758 while(qogg_stream_pageout(&format->vo, &pg) > 0)
759 {
760 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
761 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
762 }
763 }
764
765 while (1) {
766 int result = qogg_stream_flush (&format->to, &pg);
767 if (result < 0)
768 fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
769 if (result <= 0)
770 break;
771 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
772 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
773 }
774
775 if(cls.capturevideo.soundrate)
776 {
777 while (1) {
778 int result = qogg_stream_flush (&format->vo, &pg);
779 if (result < 0)
780 fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
781 if (result <= 0)
782 break;
783 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
784 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
785 }
786
790 }
791
793 qtheora_clear(&format->ts);
795
796 Mem_Free(format->yuv[0].y);
797 Mem_Free(format->yuv[0].u);
798 Mem_Free(format->yuv[0].v);
799 Mem_Free(format->yuv[1].y);
800 Mem_Free(format->yuv[1].u);
801 Mem_Free(format->yuv[1].v);
803
804 FS_Close(cls.capturevideo.videofile);
805 cls.capturevideo.videofile = NULL;
806}
807
809{
811 yuv_buffer *yuv;
812 int x, y;
813 int blockr, blockg, blockb;
814 unsigned char *b;
815 int w = cls.capturevideo.width;
816 int h = cls.capturevideo.height;
817 int inpitch = w*4;
818
819 yuv = &format->yuv[format->yuvi];
820
821 for(y = 0; y < h; ++y)
822 {
823 for(b = in + (h-1-y)*w*4, x = 0; x < w; ++x)
824 {
825 blockr = b[2];
826 blockg = b[1];
827 blockb = b[0];
828 yuv->y[x + yuv->y_stride * y] =
829 cls.capturevideo.yuvnormalizetable[0][cls.capturevideo.rgbtoyuvscaletable[0][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[0][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[0][2][blockb]];
830 b += 4;
831 }
832
833 if ((y & 1) == 0 && y/2 < h/2) // if h is odd, this skips the last row
834 {
835 for(b = in + (h-2-y)*w*4, x = 0; x < w/2; ++x)
836 {
837 blockr = (b[2] + b[6] + b[inpitch+2] + b[inpitch+6]) >> 2;
838 blockg = (b[1] + b[5] + b[inpitch+1] + b[inpitch+5]) >> 2;
839 blockb = (b[0] + b[4] + b[inpitch+0] + b[inpitch+4]) >> 2;
840 yuv->u[x + yuv->uv_stride * (y/2)] =
841 cls.capturevideo.yuvnormalizetable[1][cls.capturevideo.rgbtoyuvscaletable[1][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[1][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[1][2][blockb] + 128];
842 yuv->v[x + yuv->uv_stride * (y/2)] =
843 cls.capturevideo.yuvnormalizetable[2][cls.capturevideo.rgbtoyuvscaletable[2][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[2][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[2][2][blockb] + 128];
844 b += 8;
845 }
846 }
847 }
848}
849
850static void SCR_CaptureVideo_Ogg_VideoFrames(int num, u8 *in)
851{
853 ogg_packet pt;
854
855 // data is in cls.capturevideo.outbuffer as BGRA and has size width*height
856
857 if(format->yuvi >= 0)
858 {
859 // send the previous frame
860 while(format->lastnum-- > 0)
861 {
862 qtheora_encode_YUVin(&format->ts, &format->yuv[format->yuvi]);
863
864 while(qtheora_encode_packetout(&format->ts, false, &pt))
865 qogg_stream_packetin(&format->to, &pt);
866
868 }
869 }
870
871 format->yuvi = (format->yuvi + 1) % 2;
873 format->lastnum = num;
874
875 // TODO maybe send num-1 frames from here already
876}
877
878typedef int channelmapping_t[8];
880{
881 { 0, -1, -1, -1, -1, -1, -1, -1 }, // mono
882 { 0, 1, -1, -1, -1, -1, -1, -1 }, // stereo
883 { 0, 1, 2, -1, -1, -1, -1, -1 }, // L C R
884 { 0, 1, 2, 3, -1, -1, -1, -1 }, // surround40
885 { 0, 2, 3, 4, 1, -1, -1, -1 }, // FL FC FR RL RR
886 { 0, 2, 3, 4, 1, 5, -1, -1 }, // surround51
887 { 0, 2, 3, 4, 1, 5, 6, -1 }, // (not defined by vorbis spec)
888 { 0, 2, 3, 4, 1, 5, 6, 7 } // surround71 (not defined by vorbis spec)
889};
890
892{
894 float **vorbis_buffer;
895 size_t i;
896 int j;
897 ogg_packet pt;
898 int *map = mapping[bound(1, cls.capturevideo.soundchannels, 8) - 1];
899
900 vorbis_buffer = qvorbis_analysis_buffer(&format->vd, (int)length);
901 for(j = 0; j < cls.capturevideo.soundchannels; ++j)
902 {
903 float *b = vorbis_buffer[map[j]];
904 for(i = 0; i < length; ++i)
905 b[i] = paintbuffer[i].sample[j];
906 }
908
909 while(qvorbis_analysis_blockout(&format->vd, &format->vb) == 1)
910 {
913
914 while(qvorbis_bitrate_flushpacket(&format->vd, &pt))
915 qogg_stream_packetin(&format->vo, &pt);
916 }
917
919}
920
922{
923 char vabuf[1024];
924 cls.capturevideo.format = CAPTUREVIDEOFORMAT_OGG_VORBIS_THEORA;
925 cls.capturevideo.formatextension = "ogv";
926 cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
927 if (!cls.capturevideo.videofile)
928 {
929 Con_Printf(CON_ERROR "Failed to open video file \"%s\", cancelling video capture.\n", vabuf);
930 cls.capturevideo.error = true;
931 return;
932 }
933 cls.capturevideo.writeEndVideo = SCR_CaptureVideo_Ogg_EndVideo;
934 cls.capturevideo.writeVideoFrame = SCR_CaptureVideo_Ogg_VideoFrames;
935 cls.capturevideo.writeSoundFrame = SCR_CaptureVideo_Ogg_SoundFrame;
936 cls.capturevideo.formatspecific = Mem_Alloc(tempmempool, sizeof(capturevideostate_ogg_formatspecific_t));
937 {
939 int num, denom, i;
940 ogg_page pg;
941 ogg_packet pt, pt2, pt3;
944 theora_info ti;
945 int vp3compat;
946
947 format->serial1 = rand();
948 qogg_stream_init(&format->to, format->serial1);
949
950 if(cls.capturevideo.soundrate)
951 {
952 do
953 {
954 format->serial2 = rand();
955 }
956 while(format->serial1 == format->serial2);
957 qogg_stream_init(&format->vo, format->serial2);
958 }
959
960 format->videopage.len = format->audiopage.len = 0;
961
963 ti.frame_width = cls.capturevideo.width;
964 ti.frame_height = cls.capturevideo.height;
965 ti.width = (ti.frame_width + 15) & ~15;
966 ti.height = (ti.frame_height + 15) & ~15;
967 //ti.offset_x = ((ti.width - ti.frame_width) / 2) & ~1;
968 //ti.offset_y = ((ti.height - ti.frame_height) / 2) & ~1;
969
970 for(i = 0; i < 2; ++i)
971 {
972 format->yuv[i].y_width = ti.width;
973 format->yuv[i].y_height = ti.height;
974 format->yuv[i].y_stride = ti.width;
975 format->yuv[i].uv_width = ti.width / 2;
976 format->yuv[i].uv_height = ti.height / 2;
977 format->yuv[i].uv_stride = ti.width / 2;
978 format->yuv[i].y = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].y_stride * format->yuv[i].y_height);
979 format->yuv[i].u = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].uv_stride * format->yuv[i].uv_height);
980 format->yuv[i].v = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].uv_stride * format->yuv[i].uv_height);
981 }
982 format->yuvi = -1; // -1: no frame valid yet, write into 0
983
984 FindFraction(cls.capturevideo.framerate / cls.capturevideo.framestep, &num, &denom, 1001);
985 ti.fps_numerator = num;
986 ti.fps_denominator = denom;
987
988 FindFraction(1 / vid_pixelheight.value, &num, &denom, 1000);
989 ti.aspect_numerator = num;
990 ti.aspect_denominator = denom;
991
994
995 ti.quick_p = true; // http://mlblog.osdir.com/multimedia.ogg.theora.general/2004-07/index.shtml
996 ti.dropframes_p = false;
997
1000
1001 if(ti.target_bitrate <= 0)
1002 {
1003 ti.target_bitrate = -1;
1004 ti.keyframe_data_target_bitrate = (unsigned int)-1;
1005 }
1006 else
1007 {
1009
1010 if(ti.target_bitrate < 45000 || ti.target_bitrate > 2000000)
1011 Con_DPrintf("WARNING: requesting an odd bitrate for theora (sensible values range from 45 to 2000 kbps)\n");
1012 }
1013
1014 if(ti.quality < 0 || ti.quality > 63)
1015 {
1016 ti.quality = 63;
1017 if(ti.target_bitrate <= 0)
1018 {
1019 ti.target_bitrate = 0x7FFFFFFF;
1020 ti.keyframe_data_target_bitrate = 0x7FFFFFFF;
1021 }
1022 }
1023
1024 // this -1 magic is because ti.keyframe_frequency and ti.keyframe_mindistance use different metrics
1030
1033
1034 qtheora_encode_init(&format->ts, &ti);
1035 qtheora_info_clear(&ti);
1036
1038 {
1039 vp3compat = 1;
1040 qtheora_control(&format->ts, TH_ENCCTL_SET_VP3_COMPATIBLE, &vp3compat, sizeof(vp3compat));
1041 if(!vp3compat)
1042 Con_DPrintf("Warning: theora stream is not fully VP3 compatible\n");
1043 }
1044
1045 // vorbis?
1046 if(cls.capturevideo.soundrate)
1047 {
1049 qvorbis_encode_init_vbr(&format->vi, cls.capturevideo.soundchannels, cls.capturevideo.soundrate, bound(-1, cl_capturevideo_ogg_vorbis_quality.value, 10) * 0.099);
1052 qvorbis_block_init(&format->vd, &format->vb);
1053 }
1054
1056
1057 /* create the remaining theora headers */
1058 qtheora_encode_header(&format->ts, &pt);
1059 qogg_stream_packetin(&format->to, &pt);
1060 if (qogg_stream_pageout (&format->to, &pg) != 1)
1061 fprintf (stderr, "Internal Ogg library error.\n");
1062 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
1063 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
1064
1066 qogg_stream_packetin(&format->to, &pt);
1067 qtheora_encode_tables(&format->ts, &pt);
1068 qogg_stream_packetin (&format->to, &pt);
1069
1071
1072 if(cls.capturevideo.soundrate)
1073 {
1074 qvorbis_analysis_headerout(&format->vd, &vc, &pt, &pt2, &pt3);
1075 qogg_stream_packetin(&format->vo, &pt);
1076 if (qogg_stream_pageout (&format->vo, &pg) != 1)
1077 fprintf (stderr, "Internal Ogg library error.\n");
1078 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
1079 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
1080
1081 qogg_stream_packetin(&format->vo, &pt2);
1082 qogg_stream_packetin(&format->vo, &pt3);
1083
1085 }
1086
1087 for(;;)
1088 {
1089 int result = qogg_stream_flush (&format->to, &pg);
1090 if (result < 0)
1091 fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
1092 if (result <= 0)
1093 break;
1094 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
1095 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
1096 }
1097
1098 if(cls.capturevideo.soundrate)
1099 for(;;)
1100 {
1101 int result = qogg_stream_flush (&format->vo, &pg);
1102 if (result < 0)
1103 fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
1104 if (result <= 0)
1105 break;
1106 FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
1107 FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
1108 }
1109 }
1110}
static int(* qvorbis_encode_init_vbr)(vorbis_info *vi, long channels, long rate, float base_quality)
Definition cap_ogg.c:287
static void SCR_CaptureVideo_Ogg_FlushInterleaving(void)
Definition cap_ogg.c:697
static void(* qvorbis_comment_init)(vorbis_comment *vc)
Definition cap_ogg.c:257
static int(* qvorbis_block_clear)(vorbis_block *vb)
Definition cap_ogg.c:261
void SCR_CaptureVideo_Ogg_Init(void)
Definition cap_ogg.c:577
static int(* qvorbis_analysis_blockout)(vorbis_dsp_state *v, vorbis_block *vb)
Definition cap_ogg.c:277
static void(* qtheora_clear)(theora_state *t)
Definition cap_ogg.c:442
static void SCR_CaptureVideo_Ogg_VideoFrames(int num, u8 *in)
Definition cap_ogg.c:850
static int(* qtheora_encode_comment)(theora_comment *tc, ogg_packet *op)
Definition cap_ogg.c:438
static float **(* qvorbis_analysis_buffer)(vorbis_dsp_state *v, int vals)
Definition cap_ogg.c:275
static int(* qtheora_control)(theora_state *th, int req, void *buf, size_t buf_sz)
Definition cap_ogg.c:446
static double(* qvorbis_granule_time)(vorbis_dsp_state *v, int64_t granulepos)
Definition cap_ogg.c:263
static int(* qvorbis_analysis_init)(vorbis_dsp_state *v, vorbis_info *vi)
Definition cap_ogg.c:268
static int(* qvorbis_block_init)(vorbis_dsp_state *v, vorbis_block *vb)
Definition cap_ogg.c:260
#define TH_ENCCTL_SET_VP3_COMPATIBLE
Definition cap_ogg.c:297
static int(* qvorbis_bitrate_flushpacket)(vorbis_dsp_state *vd, ogg_packet *op)
Definition cap_ogg.c:281
static dllfunction_t vorbisencfuncs[]
Definition cap_ogg.c:460
static void(* qtheora_info_init)(theora_info *c)
Definition cap_ogg.c:440
static int(* qvorbis_commentheader_out)(vorbis_comment *vc, ogg_packet *op)
Definition cap_ogg.c:269
static void SCR_CaptureVideo_Ogg_Interleave(void)
Definition cap_ogg.c:639
channelmapping_t mapping[8]
Definition cap_ogg.c:879
static dllfunction_t vorbisfuncs[]
Definition cap_ogg.c:466
static cvar_t cl_capturevideo_ogg_theora_keyframe_auto_threshold
Definition cap_ogg.c:14
static cvar_t cl_capturevideo_ogg_theora_sharpness
Definition cap_ogg.c:16
static int(* qvorbis_analysis_wrote)(vorbis_dsp_state *v, int vals)
Definition cap_ogg.c:276
static int(* qvorbis_analysis)(vorbis_block *vb, ogg_packet *op)
Definition cap_ogg.c:278
static int(* qvorbis_bitrate_addblock)(vorbis_block *vb)
Definition cap_ogg.c:280
static dllhandle_t og_dll
Definition cap_ogg.c:506
static dllhandle_t ve_dll
Definition cap_ogg.c:506
static int(* qtheora_encode_init)(theora_state *th, theora_info *ti)
Definition cap_ogg.c:433
static void SCR_CaptureVideo_Ogg_ConvertFrame_BGRA_to_YUV(u8 *in)
Definition cap_ogg.c:808
static int(* qvorbis_analysis_headerout)(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code)
Definition cap_ogg.c:270
static int(* qogg_stream_clear)(ogg_stream_state *os)
Definition cap_ogg.c:112
static void(* qvorbis_info_init)(vorbis_info *vi)
Definition cap_ogg.c:255
static dllhandle_t vo_dll
Definition cap_ogg.c:506
static int(* qtheora_encode_YUVin)(theora_state *t, yuv_buffer *yuv)
Definition cap_ogg.c:434
static void(* qtheora_info_clear)(theora_info *c)
Definition cap_ogg.c:441
#define LOAD_FORMATSPECIFIC_OGG()
Definition cap_ogg.c:637
static cvar_t cl_capturevideo_ogg_theora_vp3compat
Definition cap_ogg.c:8
void SCR_CaptureVideo_Ogg_BeginVideo(void)
Definition cap_ogg.c:921
static cvar_t cl_capturevideo_ogg_theora_bitrate
Definition cap_ogg.c:10
static int(* qtheora_encode_tables)(theora_state *t, ogg_packet *op)
Definition cap_ogg.c:439
theora_colorspace
A Colorspace.
Definition cap_ogg.c:316
@ OC_CS_ITU_REC_470BG
This is the best option for 'PAL' content.
Definition cap_ogg.c:319
@ OC_CS_NSPACES
This marks the end of the defined colorspaces.
Definition cap_ogg.c:320
@ OC_CS_ITU_REC_470M
This is the best option for 'NTSC' content.
Definition cap_ogg.c:318
@ OC_CS_UNSPECIFIED
The colorspace is unknown or unspecified.
Definition cap_ogg.c:317
void SCR_CaptureVideo_Ogg_CloseDLL(void)
Definition cap_ogg.c:598
static void(* qtheora_comment_clear)(theora_comment *tc)
Definition cap_ogg.c:444
static cvar_t cl_capturevideo_ogg_theora_keyframe_maxinterval
Definition cap_ogg.c:12
static void(* qtheora_comment_init)(theora_comment *tc)
Definition cap_ogg.c:443
static cvar_t cl_capturevideo_ogg_theora_keyframe_bitrate_multiplier
Definition cap_ogg.c:11
static double(* qtheora_granule_time)(theora_state *th, int64_t granulepos)
Definition cap_ogg.c:445
static qbool SCR_CaptureVideo_Ogg_OpenLibrary(void)
Definition cap_ogg.c:508
static int(* qogg_stream_pageout)(ogg_stream_state *os, ogg_page *og)
Definition cap_ogg.c:106
static cvar_t cl_capturevideo_ogg_theora_quality
Definition cap_ogg.c:9
static void SCR_CaptureVideo_Ogg_EndVideo(void)
Definition cap_ogg.c:715
int channelmapping_t[8]
Definition cap_ogg.c:878
static dllfunction_t oggfuncs[]
Definition cap_ogg.c:449
static cvar_t cl_capturevideo_ogg_theora_keyframe_mininterval
Definition cap_ogg.c:13
static int(* qogg_stream_packetin)(ogg_stream_state *os, ogg_packet *op)
Definition cap_ogg.c:105
static void(* qvorbis_comment_clear)(vorbis_comment *vc)
Definition cap_ogg.c:258
static int64_t(* qogg_page_granulepos)(ogg_page *og)
Definition cap_ogg.c:113
static dllfunction_t theorafuncs[]
Definition cap_ogg.c:488
theora_pixelformat
A Chroma subsampling.
Definition cap_ogg.c:330
@ OC_PF_444
No chroma subsampling at all (4:4:4)
Definition cap_ogg.c:334
@ OC_PF_422
Horizonatal chroma subsampling by 2 (4:2:2)
Definition cap_ogg.c:333
@ OC_PF_420
Chroma subsampling by 2 in each direction (4:2:0)
Definition cap_ogg.c:331
@ OC_PF_RSVD
Reserved value.
Definition cap_ogg.c:332
static void(* qvorbis_info_clear)(vorbis_info *vi)
Definition cap_ogg.c:256
static int(* qtheora_encode_header)(theora_state *t, ogg_packet *op)
Definition cap_ogg.c:437
static int(* qogg_stream_flush)(ogg_stream_state *os, ogg_page *og)
Definition cap_ogg.c:107
static cvar_t cl_capturevideo_ogg_vorbis_quality
Definition cap_ogg.c:17
static cvar_t cl_capturevideo_ogg_theora_noise_sensitivity
Definition cap_ogg.c:15
static void SCR_CaptureVideo_Ogg_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length)
Definition cap_ogg.c:891
qbool SCR_CaptureVideo_Ogg_Available(void)
Definition cap_ogg.c:593
static void(* qvorbis_dsp_clear)(vorbis_dsp_state *v)
Definition cap_ogg.c:262
static dllhandle_t th_dll
Definition cap_ogg.c:506
static int(* qogg_stream_init)(ogg_stream_state *os, int serialno)
Definition cap_ogg.c:111
static int(* qtheora_encode_packetout)(theora_state *t, int last_p, ogg_packet *op)
Definition cap_ogg.c:435
client_static_t cls
Definition cl_main.c:116
cvar_t vid_pixelheight
Definition cl_screen.c:58
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
void FindFraction(double val, int *num, int *denom, int denomMax)
Definition common.c:1436
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_ERROR
Definition console.h:102
void() predraw
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
fs_offset_t FS_Write(qfile_t *file, const void *data, size_t datasize)
Definition fs.c:3019
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
Definition fs.c:2901
static int(ZEXPORT *qz_inflate)(z_stream *strm
int FS_Close(qfile_t *file)
Definition fs.c:2970
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
GLenum GLuint GLenum GLsizei length
Definition glquake.h:657
const GLdouble * v
Definition glquake.h:762
GLint GLint GLint GLsizei GLsizei GLenum format
Definition glquake.h:649
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
GLsizeiptr const GLvoid * data
Definition glquake.h:639
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
#define max(A, B)
Definition mathlib.h:38
#define bound(min, num, max)
Definition mathlib.h:34
int i
#define NULL
Definition qtypes.h:12
uint8_t u8
Definition qtypes.h:35
bool qbool
Definition qtypes.h:9
dp_FragColor b
void vec2 tc
channel_t channels[MAX_CHANNELS]
Definition snd_main.c:128
static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE]
Definition snd_mix.c:26
void * ptr
Definition cap_ogg.c:218
struct alloc_chain * next
Definition cap_ogg.c:219
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
long bytes
Definition cap_ogg.c:79
int64_t packetno
Definition cap_ogg.c:85
unsigned char * packet
Definition cap_ogg.c:78
long e_o_s
Definition cap_ogg.c:81
int64_t granulepos
Definition cap_ogg.c:83
long b_o_s
Definition cap_ogg.c:80
unsigned char * header
Definition cap_ogg.c:31
long body_len
Definition cap_ogg.c:34
long header_len
Definition cap_ogg.c:32
unsigned char * body
Definition cap_ogg.c:33
int64_t granulepos
Definition cap_ogg.c:70
int * lacing_vals
Definition cap_ogg.c:47
long lacing_storage
Definition cap_ogg.c:51
unsigned char * body_data
Definition cap_ogg.c:41
long lacing_returned
Definition cap_ogg.c:54
long body_returned
Definition cap_ogg.c:44
int64_t * granule_vals
Definition cap_ogg.c:48
int64_t packetno
Definition cap_ogg.c:65
long body_storage
Definition cap_ogg.c:42
long lacing_packet
Definition cap_ogg.c:53
unsigned char * data
Definition cap_ogg.c:93
int headerbytes
Definition cap_ogg.c:99
unsigned char * buffer
Definition cap_ogg.c:23
unsigned char * ptr
Definition cap_ogg.c:24
exported for capturevideo so ogg can see all channels
Definition snd_main.h:196
Comment header metadata.
Definition cap_ogg.c:426
int comments
The total number of comment string vectors.
Definition cap_ogg.c:429
char ** user_comments
An array of comment string vectors.
Definition cap_ogg.c:427
int * comment_lengths
An array of corresponding string vector lengths in bytes.
Definition cap_ogg.c:428
char * vendor
The vendor string identifying the encoder, null terminated.
Definition cap_ogg.c:430
Theora bitstream info.
Definition cap_ogg.c:357
int32_t keyframe_auto_threshold
Definition cap_ogg.c:387
int target_bitrate
nominal bitrate in bits per second
Definition cap_ogg.c:369
int keyframe_auto_p
Definition cap_ogg.c:382
uint32_t frame_height
display frame height
Definition cap_ogg.c:361
int quick_p
Quick encode/decode.
Definition cap_ogg.c:371
uint32_t aspect_denominator
pixel aspect ratio denominator
Definition cap_ogg.c:367
uint32_t fps_numerator
frame rate numerator
Definition cap_ogg.c:364
uint32_t keyframe_data_target_bitrate
Definition cap_ogg.c:386
theora_colorspace colorspace
colorspace
Definition cap_ogg.c:368
theora_pixelformat pixelformat
chroma subsampling mode to expect
Definition cap_ogg.c:392
uint32_t width
encoded frame width
Definition cap_ogg.c:358
void * codec_setup
Definition cap_ogg.c:378
int quality
Nominal quality setting, 0-63.
Definition cap_ogg.c:370
unsigned char version_minor
Definition cap_ogg.c:375
unsigned char version_major
Definition cap_ogg.c:374
uint32_t offset_x
horizontal offset of the displayed frame
Definition cap_ogg.c:362
uint32_t keyframe_frequency_force
Definition cap_ogg.c:384
unsigned char version_subminor
Definition cap_ogg.c:376
uint32_t aspect_numerator
pixel aspect ratio numerator
Definition cap_ogg.c:366
uint32_t height
encoded frame height
Definition cap_ogg.c:359
uint32_t keyframe_frequency
Definition cap_ogg.c:383
uint32_t keyframe_mindistance
Definition cap_ogg.c:388
uint32_t offset_y
vertical offset of the displayed frame
Definition cap_ogg.c:363
int32_t noise_sensitivity
Definition cap_ogg.c:389
int32_t sharpness
Definition cap_ogg.c:390
uint32_t frame_width
display frame width
Definition cap_ogg.c:360
int dropframes_p
Definition cap_ogg.c:381
uint32_t fps_denominator
frame rate denominator
Definition cap_ogg.c:365
Codec internal state and context.
Definition cap_ogg.c:398
theora_info * i
Definition cap_ogg.c:399
void * internal_encode
Definition cap_ogg.c:402
int64_t granulepos
Definition cap_ogg.c:400
void * internal_decode
Definition cap_ogg.c:403
struct alloc_chain * reap
Definition cap_ogg.c:200
long localalloc
Definition cap_ogg.c:198
long totaluse
Definition cap_ogg.c:199
void * localstore
Definition cap_ogg.c:196
long res_bits
Definition cap_ogg.c:206
oggpack_buffer opb
Definition cap_ogg.c:181
vorbis_dsp_state * vd
Definition cap_ogg.c:192
long localtop
Definition cap_ogg.c:197
float ** pcm
Definition cap_ogg.c:180
int64_t granulepos
Definition cap_ogg.c:190
long time_bits
Definition cap_ogg.c:204
long floor_bits
Definition cap_ogg.c:205
int64_t sequence
Definition cap_ogg.c:191
long glue_bits
Definition cap_ogg.c:203
void * internal
Definition cap_ogg.c:208
int * comment_lengths
Definition cap_ogg.c:234
char ** user_comments
Definition cap_ogg.c:233
char * vendor
Definition cap_ogg.c:236
int64_t time_bits
Definition cap_ogg.c:171
int64_t floor_bits
Definition cap_ogg.c:172
int64_t glue_bits
Definition cap_ogg.c:170
float ** pcm
Definition cap_ogg.c:153
int64_t res_bits
Definition cap_ogg.c:173
int64_t sequence
Definition cap_ogg.c:168
void * backend_state
Definition cap_ogg.c:175
vorbis_info * vi
Definition cap_ogg.c:151
float ** pcmret
Definition cap_ogg.c:154
int64_t granulepos
Definition cap_ogg.c:167
long rate
Definition cap_ogg.c:121
long bitrate_lower
Definition cap_ogg.c:140
int version
Definition cap_ogg.c:119
long bitrate_upper
Definition cap_ogg.c:138
int channels
Definition cap_ogg.c:120
long bitrate_nominal
Definition cap_ogg.c:139
long bitrate_window
Definition cap_ogg.c:141
void * codec_setup
Definition cap_ogg.c:143
int y_height
Height of the luminance plane.
Definition cap_ogg.c:301
int uv_height
Height of the chroma planes.
Definition cap_ogg.c:305
unsigned char * y
Pointer to start of luminance data.
Definition cap_ogg.c:307
unsigned char * u
Pointer to start of Cb data.
Definition cap_ogg.c:308
int uv_width
Width of the Cb and Cr chroma planes.
Definition cap_ogg.c:304
int y_stride
Offset in bytes between successive rows.
Definition cap_ogg.c:302
unsigned char * v
Pointer to start of Cr data.
Definition cap_ogg.c:309
int y_width
Width of the Y' luminance plane.
Definition cap_ogg.c:300
int uv_stride
Offset between successive chroma rows.
Definition cap_ogg.c:306
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:724
void * dllhandle_t
Definition sys.h:169
qbool Sys_LoadDependency(const char **dllnames, dllhandle_t *handle, const dllfunction_t *fcts)
Definition sys_shared.c:131
void Sys_FreeLibrary(dllhandle_t *handle)
Definition sys_shared.c:245
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92