int main() { ogg_sync_state oy; ogg_stream_state os; int init=0; ogg_packet op; kate_state k; kate_info ki; kate_comment kc; const kate_event *ev; /* for the benefit of windows, which mangles data otherwise */ set_binary_file(stdin); /* we initialize ogg and kate info/comment structures */ ogg_sync_init(&oy); kate_info_init(&ki); kate_comment_init(&kc); /* First, read the headers, which must appear first in a Kate stream. When kate_decode_header returns a positive number, all headers have been seen and we're ready to decode data. */ do { get_packet(&oy,&os,&init,&op); } while (kate_ogg_decode_headerin(&ki,&kc,&op)==0); /* We now have all the information we need from the headers, so we can initialize kate for decoding */ kate_decode_init(&k,&ki); /* We can now read data, until kate_decode_packetin returns a positive number, signaling the end of the stream */ while (1) { if (get_packet(&oy,&os,&init,&op)) break; if (kate_ogg_decode_packetin(&k,&op)>0) break; /* we may have an event (eg, text) */ if (kate_decode_eventout(&k,&ev)==0) { printf("Kate stream has text: %s\n",ev->text); } } /* That's it, we can now cleanup */ ogg_stream_clear(&os); ogg_sync_clear(&oy); kate_clear(&k); kate_info_clear(&ki); kate_comment_clear(&kc); return 0; }
int main() { /* We need an Ogg stream to write to */ ogg_stream_state os; ogg_packet op; /* First, a kate_info structure needs to be created and setup for the stream to create. A kate_comment structure also has to be created. Information from both of these will get encoded into the stream headers. Last, we also need a kate_state structure, which will be initialized later. */ kate_info ki; kate_comment kc; kate_state k; kate_info_init(&ki); kate_comment_init(&kc); /* The most important part of the kate_info structure on encoding is the granule encoding information, which describes how granules and time are mapped. Here, we map one granule to one millisecond. */ ki.granule_shift=32; ki.gps_numerator=1000; ki.gps_denominator=1; /* With that done, we can initialize libkate for encoding, and initialize libogg as well: */ kate_encode_init(&k,&ki); ogg_stream_init(&os,0x12345678); /* for the benefit of windows, which mangles data otherwise */ set_binary_file(stdout); /* Before you can create events, headers need to be sent. Here, we'll just send the headers directly, but you will usually want to add regions, styles, etc to the headers before doing so: */ while (kate_ogg_encode_headers(&k,&kc,&op)==0) { ogg_stream_packetin(&os,&op); ogg_packet_clear(&op); } flush_page(&os); /* Events can now be created, and we'll just create and send a single one here, starting at time 10 seconds, and stopping at time 15 seconds. */ #define text "Hello, world!" kate_ogg_encode_text(&k,10.0,15.0,text,strlen(text)+1,&op); ogg_stream_packetin(&os,&op); ogg_packet_clear(&op); flush_page(&os); /* When we're done, we can tell libkate so an "end of stream" packet will be generated, and clear the resources we've been using: */ kate_ogg_encode_finish(&k,-1,&op); ogg_stream_packetin(&os,&op); ogg_packet_clear(&op); flush_page(&os); ogg_stream_clear(&os); kate_clear(&k); kate_info_clear(&ki); kate_comment_clear(&kc); /* That's it, we now have created a full kate stream. You may now want to decode it, or multiplex it with a Theora video, etc. */ return 0; }
static GstStateChangeReturn gst_kate_enc_change_state (GstElement * element, GstStateChange transition) { GstKateEnc *ke = GST_KATE_ENC (element); GstStateChangeReturn res; int ret; GST_INFO_OBJECT (ke, "gst_kate_enc_change_state"); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: ke->tags = gst_tag_list_new_empty (); break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_DEBUG_OBJECT (ke, "READY -> PAUSED, initializing kate state"); ret = kate_info_init (&ke->ki); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to initialize kate info structure: %s", gst_kate_util_get_error_message (ret)); break; } if (ke->language) { ret = kate_info_set_language (&ke->ki, ke->language); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to set stream language: %s", gst_kate_util_get_error_message (ret)); break; } } if (ke->category) { ret = kate_info_set_category (&ke->ki, ke->category); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to set stream category: %s", gst_kate_util_get_error_message (ret)); break; } } ret = kate_info_set_original_canvas_size (&ke->ki, ke->original_canvas_width, ke->original_canvas_height); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to set original canvas size: %s", gst_kate_util_get_error_message (ret)); break; } ret = kate_comment_init (&ke->kc); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to initialize kate comment structure: %s", gst_kate_util_get_error_message (ret)); break; } ret = kate_encode_init (&ke->k, &ke->ki); if (ret < 0) { GST_WARNING_OBJECT (ke, "failed to initialize kate state: %s", gst_kate_util_get_error_message (ret)); break; } ke->headers_sent = FALSE; ke->initialized = TRUE; ke->last_timestamp = 0; ke->latest_end_time = 0; ke->format = GST_KATE_FORMAT_UNDEFINED; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; case GST_STATE_CHANGE_READY_TO_NULL: gst_tag_list_unref (ke->tags); ke->tags = NULL; break; default: break; } res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (res == GST_STATE_CHANGE_FAILURE) { GST_WARNING_OBJECT (ke, "Parent failed to change state"); return res; } switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_DEBUG_OBJECT (ke, "PAUSED -> READY, clearing kate state"); if (ke->initialized) { kate_clear (&ke->k); kate_info_clear (&ke->ki); kate_comment_clear (&ke->kc); ke->initialized = FALSE; ke->last_timestamp = 0; ke->latest_end_time = 0; } gst_event_replace (&ke->pending_segment, NULL); break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } GST_DEBUG_OBJECT (ke, "State change done"); return res; }