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