1 /* Copyright (C) 2008 Vincent Penquerc'h.
2    This file is part of the Kate codec library.
3    Written by Vincent Penquerc'h.
4 
5    Use, distribution and reproduction of this library is governed
6    by a BSD style source license included with this source in the
7    file 'COPYING'. Please read these terms before distributing. */
8 
9 
10 #define KATE_INTERNAL
11 #include "kate_internal.h"
12 
13 #ifdef HAVE_STDLIB_H
14 #include <stdlib.h>
15 #endif
16 #ifdef HAVE_STRING_H
17 #include <string.h>
18 #endif
19 #include "kate/oggkate.h"
20 #include "kate_encode_state.h"
21 
kate_packet_wrap_ogg(kate_packet * kp,const ogg_packet * op)22 static void kate_packet_wrap_ogg(kate_packet *kp,const ogg_packet *op)
23 {
24   kate_packet_wrap(kp,op->bytes,op->packet);
25 }
26 
kate_packet_create_ogg(kate_packet * kp,ogg_packet * op,kate_encode_state * kes,int eos)27 static int kate_packet_create_ogg(kate_packet *kp,ogg_packet *op,kate_encode_state *kes,int eos)
28 {
29   op->b_o_s=(kes->packetno==0);
30   op->e_o_s=eos;
31   op->packetno=kes->packetno;
32   op->granulepos=kes->granulepos;
33   op->bytes=kp->nbytes;
34   op->packet=_ogg_malloc(kp->nbytes);
35   if (!op->packet) {
36     kate_free(kp->data);
37     return KATE_E_OUT_OF_MEMORY;
38   }
39   memcpy(op->packet,kp->data,kp->nbytes);
40   kate_free(kp->data);
41   return 0;
42 }
43 
44 /**
45   Encodes a Kate header to an Ogg packet
46   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
47   \param k the kate_state structure to encode headers for
48   \param kc the comments to encode in headers
49   \param op the ogg_packet to encode headers to
50   \returns 0 success
51   \returns 1 success, and all headers have been encoded
52   \returns KATE_E_* error
53  */
kate_ogg_encode_headers(kate_state * k,kate_comment * kc,ogg_packet * op)54 int kate_ogg_encode_headers(kate_state *k,kate_comment *kc,ogg_packet *op)
55 {
56   kate_packet kp;
57   int ret=kate_encode_headers(k,kc,&kp);
58   if (ret<0) return ret;
59   if (ret>0) return ret; /* no more headers, no packet created */
60   return kate_packet_create_ogg(&kp,op,k->kes,0);
61 }
62 
63 /**
64   Encodes a text data packet to an Ogg packet
65   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
66   \param k the kate_state structure to encode headers for
67   \param start_time the start time, in seconds, of the event
68   \param stop_time the stop time, in seconds, of the event
69   \param text the text this event will hold (may be empty if none)
70   \param sz the size, in bytes, of the text
71   \param op the ogg_packet to encode the packet to
72   \returns 0 success
73   \returns KATE_E_* error
74  */
kate_ogg_encode_text(kate_state * k,kate_float start_time,kate_float stop_time,const char * text,size_t sz,ogg_packet * op)75 int kate_ogg_encode_text(kate_state *k,kate_float start_time,kate_float stop_time,const char *text,size_t sz,ogg_packet *op)
76 {
77   kate_packet kp;
78   int ret=kate_encode_text(k,start_time,stop_time,text,sz,&kp);
79   if (ret<0) return ret;
80   return kate_packet_create_ogg(&kp,op,k->kes,0);
81 }
82 
83 /**
84   Encodes a text data packet to an Ogg packet
85   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
86   \param k the kate_state structure to encode headers for
87   \param start_time the start time, in seconds, of the event
88   \param stop_time the stop time, in seconds, of the event
89   \param text the text this event will hold (may be empty if none)
90   \param sz the size, in bytes, of the text
91   \param op the ogg_packet to encode the packet to
92   \returns 0 success
93   \returns KATE_E_* error
94  */
kate_ogg_encode_text_raw_times(kate_state * k,kate_int64_t start_time,kate_int64_t stop_time,const char * text,size_t sz,ogg_packet * op)95 int kate_ogg_encode_text_raw_times(kate_state *k,kate_int64_t start_time,kate_int64_t stop_time,const char *text,size_t sz,ogg_packet *op)
96 {
97   kate_packet kp;
98   int ret=kate_encode_text_raw_times(k,start_time,stop_time,text,sz,&kp);
99   if (ret<0) return ret;
100   return kate_packet_create_ogg(&kp,op,k->kes,0);
101 }
102 
103 /**
104   Encodes a repeat data packet to an Ogg packet
105   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
106   \param k the kate_state structure to encode headers for
107   \param t the time at which to insert the repeat packet
108   \param threshold the minimum age an active event must be for a repeat packet to be encoded
109   \param op the ogg_packet to encode the packet to
110   \returns 0 success, and no repeat packets were needed
111   \returns 1 success, and a repeat packet was encoded
112   \returns KATE_E_* error
113  */
kate_ogg_encode_repeat(kate_state * k,kate_float t,kate_float threshold,ogg_packet * op)114 int kate_ogg_encode_repeat(kate_state *k,kate_float t,kate_float threshold,ogg_packet *op)
115 {
116   kate_packet kp;
117   int ret=kate_encode_repeat(k,t,threshold,&kp);
118   if (ret<0) return ret;
119   if (ret>0) {
120     int pret=kate_packet_create_ogg(&kp,op,k->kes,0);
121     if (pret<0) return pret;
122   }
123   return ret;
124 }
125 
126 /**
127   Encodes a repeat data packet to an Ogg packet
128   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
129   \param k the kate_state structure to encode headers for
130   \param t the time at which to insert the repeat packet
131   \param threshold the minimum age an active event must be for a repeat packet to be encoded
132   \param op the ogg_packet to encode the packet to
133   \returns 0 success, and no repeat packets were needed
134   \returns 1 success, and a repeat packet was encoded
135   \returns KATE_E_* error
136  */
kate_ogg_encode_repeat_raw_times(kate_state * k,kate_int64_t t,kate_int64_t threshold,ogg_packet * op)137 int kate_ogg_encode_repeat_raw_times(kate_state *k,kate_int64_t t,kate_int64_t threshold,ogg_packet *op)
138 {
139   kate_packet kp;
140   int ret=kate_encode_repeat_raw_times(k,t,threshold,&kp);
141   if (ret<0) return ret;
142   if (ret>0) {
143     int pret=kate_packet_create_ogg(&kp,op,k->kes,0);
144     if (pret<0) return pret;
145   }
146   return ret;
147 }
148 
149 /**
150   Encodes a keepalive data packet to an Ogg packet
151   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
152   \param k the kate_state structure to encode headers for
153   \param t the time at which to insert the keepalive packet
154   \param op the ogg_packet to encode the packet to
155   \returns 0 success
156   \returns KATE_E_* error
157  */
kate_ogg_encode_keepalive(kate_state * k,kate_float t,ogg_packet * op)158 int kate_ogg_encode_keepalive(kate_state *k,kate_float t,ogg_packet *op)
159 {
160   kate_packet kp;
161   int ret=kate_encode_keepalive(k,t,&kp);
162   if (ret<0) return ret;
163   return kate_packet_create_ogg(&kp,op,k->kes,0);
164 }
165 
166 /**
167   Encodes a keepalive data packet to an Ogg packet
168   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
169   \param k the kate_state structure to encode headers for
170   \param t the time at which to insert the keepalive packet
171   \param op the ogg_packet to encode the packet to
172   \returns 0 success
173   \returns KATE_E_* error
174  */
kate_ogg_encode_keepalive_raw_times(kate_state * k,kate_int64_t t,ogg_packet * op)175 int kate_ogg_encode_keepalive_raw_times(kate_state *k,kate_int64_t t,ogg_packet *op)
176 {
177   kate_packet kp;
178   int ret=kate_encode_keepalive_raw_times(k,t,&kp);
179   if (ret<0) return ret;
180   return kate_packet_create_ogg(&kp,op,k->kes,0);
181 }
182 
183 /**
184   Encodes an end-of-stream data packet to an Ogg packet
185   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
186   No other packet may be encoded afer an end of stream packet is encoded.
187   \param k the kate_state structure to encode headers for
188   \param t the time at which to insert the packet
189   \param op the ogg_packet to encode the packet to
190   \returns 0 success
191   \returns KATE_E_* error
192  */
kate_ogg_encode_finish(kate_state * k,kate_float t,ogg_packet * op)193 int kate_ogg_encode_finish(kate_state *k,kate_float t,ogg_packet *op)
194 {
195   kate_packet kp;
196   int ret=kate_encode_finish(k,t,&kp);
197   if (ret<0) return ret;
198   return kate_packet_create_ogg(&kp,op,k->kes,1);
199 }
200 
201 /**
202   Encodes an end-of-stream data packet to an Ogg packet
203   The kate_state structure should have been initialized with kate_decode_init or kate_encode_init.
204   No other packet may be encoded afer an end of stream packet is encoded.
205   \param k the kate_state structure to encode headers for
206   \param t the time at which to insert the packet
207   \param op the ogg_packet to encode the packet to
208   \returns 0 success
209   \returns KATE_E_* error
210  */
kate_ogg_encode_finish_raw_times(kate_state * k,kate_int64_t t,ogg_packet * op)211 int kate_ogg_encode_finish_raw_times(kate_state *k,kate_int64_t t,ogg_packet *op)
212 {
213   kate_packet kp;
214   int ret=kate_encode_finish_raw_times(k,t,&kp);
215   if (ret<0) return ret;
216   return kate_packet_create_ogg(&kp,op,k->kes,1);
217 }
218 
219 /**
220   Checks whether an Ogg packet contains a Kate identification header.
221   \param op the ogg_packet to test
222   \returns 1 success, and the packet contains a Kate identification header
223   \returns 0 success, and the packet does not contain a Kate identification header
224   \returns KATE_E_* error
225  */
kate_ogg_decode_is_idheader(const ogg_packet * op)226 int kate_ogg_decode_is_idheader(const ogg_packet *op)
227 {
228   kate_packet kp;
229   if (!op) return 0;
230   if (op->packetno!=0) return 0;
231   kate_packet_wrap_ogg(&kp,op);
232   return kate_decode_is_idheader(&kp);
233 }
234 
235 /**
236   Decodes a Kate header
237   \param ki the kate_info structure to fill from headers
238   \param kc the kate_comment structure to fill from headers
239   \param op the ogg_packet to test
240   \returns 0 success
241   \returns 1 success, and all headers have been decoded
242   \returns KATE_E_* error
243  */
kate_ogg_decode_headerin(kate_info * ki,kate_comment * kc,ogg_packet * op)244 int kate_ogg_decode_headerin(kate_info *ki,kate_comment *kc,ogg_packet *op)
245 {
246   kate_packet kp;
247   if (!op) return KATE_E_INVALID_PARAMETER;
248   kate_packet_wrap_ogg(&kp,op);
249   return kate_decode_headerin(ki,kc,&kp);
250 }
251 
252 /**
253   Decodes a Kate data packet
254   \param k the kate_state structure to decode a packet for
255   \param op the ogg_packet to test
256   \returns 0 success
257   \returns 1 success, and we're at end of stream
258   \returns KATE_E_* error
259  */
kate_ogg_decode_packetin(kate_state * k,ogg_packet * op)260 int kate_ogg_decode_packetin(kate_state *k,ogg_packet *op)
261 {
262   kate_packet kp;
263   if (!op) return KATE_E_INVALID_PARAMETER;
264   kate_packet_wrap_ogg(&kp,op);
265   return kate_decode_packetin(k,&kp);
266 }
267 
268