1 /*
2 ogmmerge -- utility for splicing together ogg bitstreams
3 from component media subtypes
4
5 p_index.cpp
6 video index
7
8 Written by Moritz Bunkus <moritz@bunkus.org>
9 Based on Xiph.org's 'oggmerge' found in their CVS repository
10 See http://www.xiph.org
11
12 Distributed under the GPL
13 see the file COPYING for details
14 or visit http://www.gnu.org/copyleft/gpl.html
15 */
16
17 #ifdef ENABLE_INDEX
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <ogg/ogg.h>
25
26 #include "ogmmerge.h"
27 #include "queue.h"
28 #include "p_index.h"
29 #include "vorbis_header_utils.h"
30
index_packetizer_c(int nserial)31 index_packetizer_c::index_packetizer_c(int nserial) throw (error_c) : q_c() {
32 serialno = create_unique_serial();
33 ogg_stream_init(&os, serialno);
34 granulepos = 0;
35 serial = nserial;
36 packetno = 0;
37 produce_header_packets();
38 }
39
~index_packetizer_c()40 index_packetizer_c::~index_packetizer_c() {
41 }
42
reset()43 void index_packetizer_c::reset() {
44 }
45
produce_header_packets()46 void index_packetizer_c::produce_header_packets() {
47 ogg_packet op;
48 stream_header sh;
49 int clen, res;
50 char *tempbuf;
51 vorbis_comment *vc;
52
53 tempbuf = (char *)malloc(sizeof(sh) + 64);
54 if (tempbuf == NULL)
55 die("malloc");
56 memset(&sh, 0, sizeof(sh));
57 strcpy(sh.streamtype, "index");
58 put_uint32(&sh.subtype[0], serial);
59 put_uint32(&sh.size, sizeof(sh));
60 put_uint64(&sh.time_unit, 10000000);
61
62 *((unsigned char *)tempbuf) = PACKET_TYPE_HEADER;
63 memcpy((char *)&tempbuf[1], &sh, sizeof(sh));
64 op.packet = (unsigned char *)tempbuf;
65 op.bytes = 1 + get_uint32(&sh.size);
66 op.b_o_s = 1;
67 op.e_o_s = 0;
68 op.packetno = 0;
69 op.granulepos = 0;
70 /* submit it */
71 ogg_stream_packetin(&os, &op);
72 packetno++;
73 flush_pages(PACKET_TYPE_HEADER);
74
75 /* Create the comments packet */
76 vc = generate_vorbis_comment(NULL);
77 clen = -1 * comments_to_buffer(vc, NULL, 0);
78 op.packet = (unsigned char *)tempbuf;
79 op.bytes = clen;
80 op.b_o_s = 0;
81 op.e_o_s = 0;
82 op.granulepos = 0;
83 op.packetno = 1;
84 if ((res = comments_to_buffer(vc, (char *)op.packet, clen)) < 0) {
85 fprintf(stderr, "FATAL: p_index: comments_to_buffer returned %d, " \
86 "clen is %d\n", res, clen);
87 exit(1);
88 }
89 ogg_stream_packetin(&os, &op);
90 flush_pages(PACKET_TYPE_COMMENT);
91 packetno++;
92 vorbis_comment_clear(vc);
93 free(vc);
94 }
95
process(idx_entry * entries,int num)96 int index_packetizer_c::process(idx_entry *entries, int num) {
97 ogg_packet op;
98 char *tempbuf;
99
100 tempbuf = (char *)malloc(num * sizeof(idx_entry) + 64);
101 if (tempbuf == NULL)
102 die("malloc");
103
104 this->serial = serial;
105
106 memcpy(&tempbuf[1], entries, num * sizeof(idx_entry));
107 tempbuf[0] = PACKET_IS_SYNCPOINT;
108 op.bytes = num * sizeof(idx_entry) + 1;
109 op.packet = (unsigned char *)tempbuf;
110 op.b_o_s = 0;
111 op.e_o_s = 1;
112 op.granulepos = 0;
113 op.packetno = packetno++;
114 ogg_stream_packetin(&os, &op);
115
116 flush_pages();
117
118 free(tempbuf);
119
120 return EMOREDATA;
121 }
122
produce_eos_packet()123 void index_packetizer_c::produce_eos_packet() {
124 }
125
make_timestamp(ogg_int64_t granulepos)126 stamp_t index_packetizer_c::make_timestamp(ogg_int64_t granulepos) {
127 return 0;
128 }
129
130 #endif // ENABLE_INDEX
131