9 /*Packs a series of octets from a given byte array into the pack buffer.
10 _opb: The pack buffer to store the octets in.
11 _buf: The byte array containing the bytes to pack.
12 _len: The number of octets to pack.*/
13 static void oc_pack_octets(oggpack_buffer
*_opb
,const char *_buf
,int _len
){
15 for(i
=0;i
<_len
;i
++)oggpackB_write(_opb
,*_buf
++,8);
20 int oc_state_flushheader(oc_theora_state
*_state
,int *_packet_state
,
21 oggpack_buffer
*_opb
,const th_quant_info
*_qinfo
,
22 const th_huff_code _codes
[TH_NHUFFMAN_TABLES
][TH_NDCT_TOKENS
],
23 const char *_vendor
,th_comment
*_tc
,ogg_packet
*_op
){
24 if(_op
==NULL
)return TH_EFAULT
;
25 switch(*_packet_state
){
26 /*Codec info header.*/
27 case OC_PACKET_INFO_HDR
:{
28 if(_state
==NULL
)return TH_EFAULT
;
30 /*Mark this packet as the info header.*/
31 oggpackB_write(_opb
,0x80,8);
32 /*Write the codec string.*/
33 oc_pack_octets(_opb
,"theora",6);
34 /*Write the codec bitstream version.*/
35 oggpackB_write(_opb
,TH_VERSION_MAJOR
,8);
36 oggpackB_write(_opb
,TH_VERSION_MINOR
,8);
37 oggpackB_write(_opb
,TH_VERSION_SUB
,8);
38 /*Describe the encoded frame.*/
39 oggpackB_write(_opb
,_state
->info
.frame_width
>>4,16);
40 oggpackB_write(_opb
,_state
->info
.frame_height
>>4,16);
41 oggpackB_write(_opb
,_state
->info
.pic_width
,24);
42 oggpackB_write(_opb
,_state
->info
.pic_height
,24);
43 oggpackB_write(_opb
,_state
->info
.pic_x
,8);
44 oggpackB_write(_opb
,_state
->info
.frame_height
-
45 _state
->info
.pic_height
-_state
->info
.pic_y
,8);
46 oggpackB_write(_opb
,_state
->info
.fps_numerator
,32);
47 oggpackB_write(_opb
,_state
->info
.fps_denominator
,32);
48 oggpackB_write(_opb
,_state
->info
.aspect_numerator
,24);
49 oggpackB_write(_opb
,_state
->info
.aspect_denominator
,24);
50 oggpackB_write(_opb
,_state
->info
.colorspace
,8);
51 oggpackB_write(_opb
,_state
->info
.target_bitrate
,24);
52 oggpackB_write(_opb
,_state
->info
.quality
,6);
53 oggpackB_write(_opb
,_state
->info
.keyframe_granule_shift
,5);
54 oggpackB_write(_opb
,_state
->info
.pixel_fmt
,2);
55 /*Spare configuration bits.*/
56 oggpackB_write(_opb
,0,3);
60 case OC_PACKET_COMMENT_HDR
:{
63 if(_tc
==NULL
)return TH_EFAULT
;
64 vendor_len
=strlen(_vendor
);
66 /*Mark this packet as the comment header.*/
67 oggpackB_write(_opb
,0x81,8);
68 /*Write the codec string.*/
69 oc_pack_octets(_opb
,"theora",6);
70 /*Write the vendor string.*/
71 oggpack_write(_opb
,vendor_len
,32);
72 oc_pack_octets(_opb
,_vendor
,vendor_len
);
73 oggpack_write(_opb
,_tc
->comments
,32);
74 for(i
=0;i
<_tc
->comments
;i
++){
75 if(_tc
->user_comments
[i
]!=NULL
){
76 oggpack_write(_opb
,_tc
->comment_lengths
[i
],32);
77 oc_pack_octets(_opb
,_tc
->user_comments
[i
],
78 _tc
->comment_lengths
[i
]);
80 else oggpack_write(_opb
,0,32);
84 /*Codec setup header.*/
85 case OC_PACKET_SETUP_HDR
:{
88 /*Mark this packet as the setup header.*/
89 oggpackB_write(_opb
,0x82,8);
90 /*Write the codec string.*/
91 oc_pack_octets(_opb
,"theora",6);
92 /*Write the quantizer tables.*/
93 oc_quant_params_pack(_opb
,_qinfo
);
94 /*Write the huffman codes.*/
95 ret
=oc_huff_codes_pack(_opb
,_codes
);
96 /*This should never happen, because we validate the tables when they
98 If you see, it's a good chance memory is being corrupted.*/
102 /*No more headers to emit.*/
105 /*This is kind of fugly: we hand the user a buffer which they do not own.
106 We will overwrite it when the next packet is output, so the user better be
107 done with it by then.
108 Vorbis is little better: it hands back buffers that it will free the next
109 time the headers are requested, or when the encoder is cleared.
110 Hopefully libogg2 will make this much cleaner.*/
111 _op
->packet
=oggpackB_get_buffer(_opb
);
112 _op
->bytes
=oggpackB_bytes(_opb
);
115 /*Is this smart? Vorbis does not even set this field.*/
117 return ++(*_packet_state
)+3;