1 /*
2 ogminfo -- utility for extracting raw streams from an OGG media file
3
4 Written by Moritz Bunkus <moritz@bunkus.org>
5 Integrated into transcode by Tilmann Bitterberg <transcode@tibit.org>
6
7 Distributed under the GPL
8 see the file COPYING for details
9 or visit http://www.gnu.org/copyleft/gpl.html
10 */
11
12 #include "transcode.h"
13 #include "libtc/libtc.h"
14 #include "tcinfo.h"
15
16 #include <sys/types.h>
17
18 #include "ioaux.h"
19 #include "tc.h"
20
21 #define NOAUDIO 0
22 #define NOVIDEO 1
23 #define NOTEXT 2
24
25 unsigned char *xaudio = NULL;
26 unsigned char *xvideo = NULL;
27 unsigned char *xtext = NULL;
28 int no[3];
29 int xraw = 0;
30
31 static int verbose_flag = TC_QUIET;
32
33 #if (HAVE_OGG && HAVE_VORBIS)
34
35 #include <ogg/ogg.h>
36 #include <vorbis/codec.h>
37
38 #include "ogmstreams.h"
39
40 #define BLOCK_SIZE 4096
41
42 #define ACVORBIS 0xffff
43 #define ACPCM 0x0001
44 #define ACMP3 0x0055
45 #define ACAC3 0x2000
46
47 typedef struct stream_t {
48 int serial;
49 int fd;
50 double sample_rate;
51 int eos, comment;
52 int sno;
53 char stype;
54 ogg_stream_state instate;
55 struct stream_t *next;
56
57 int acodec;
58 ogg_int64_t bwritten;
59
60 ogg_stream_state outstate;
61 int packetno;
62 ogg_int64_t max_granulepos;
63
64 int subnr;
65 } stream_t;
66
67 stream_t *first;
68 int nastreams = 0, nvstreams = 0, ntstreams = 0, numstreams = 0;
69 char basename[] = "stdout";
70
add_stream(stream_t * ndmx)71 static void add_stream(stream_t *ndmx) {
72 stream_t *cur = first;
73
74 if (first == NULL) {
75 first = ndmx;
76 first->next = NULL;
77 } else {
78 cur = first;
79 while (cur->next != NULL)
80 cur = cur->next;
81 cur->next = ndmx;
82 ndmx->next = NULL;
83 }
84 }
85
find_stream(int fserial)86 static stream_t *find_stream(int fserial) {
87 stream_t *cur = first;
88
89 while (cur != NULL) {
90 if (cur->serial == fserial)
91 break;
92 cur = cur->next;
93 }
94
95 return cur;
96 }
97
98 double highest_ts = 0;
99
extraction_requested(unsigned char * s,int stream,int type)100 static int extraction_requested(unsigned char *s, int stream, int type) {
101 int i;
102
103 if (no[type])
104 return 0;
105 if (strlen((char *)s) == 0)
106 return 1;
107 for (i = 0; i < strlen((char *)s); i++)
108 if (s[i] == stream)
109 return 1;
110
111 return 0;
112 }
113
flush_pages(stream_t * stream,ogg_packet * op)114 static void flush_pages(stream_t *stream, ogg_packet *op) {
115 ogg_page page;
116
117 while (ogg_stream_flush(&stream->outstate, &page)) {
118 int ih, ib;
119
120 ih = tc_pwrite(stream->fd, page.header, page.header_len);
121 if (ih != page.header_len) {
122 tc_log_error(__FILE__, "error while writing page header");
123 import_exit(1); /* XXX ugly */
124 }
125 ib = tc_pwrite(stream->fd, page.body, page.body_len);
126 if (ib != page.body_len) {
127 tc_log_error(__FILE__, "error while writing page bofy");
128 import_exit(1); /* XXX ugly */
129 }
130 if (verbose_flag & TC_DEBUG)
131 tc_log_msg(__FILE__, "x/a%d: %d + %d written", stream->sno, ih, ib);
132 }
133 }
134
write_pages(stream_t * stream,ogg_packet * op)135 static void write_pages(stream_t *stream, ogg_packet *op) {
136 ogg_page page;
137
138 while (ogg_stream_pageout(&stream->outstate, &page)) {
139 int ih, ib;
140
141 ih = tc_pwrite(stream->fd, page.header, page.header_len);
142 if (ih != page.header_len) {
143 tc_log_error(__FILE__, "error while writing page header");
144 import_exit(1); /* XXX ugly */
145 }
146 ib = tc_pwrite(stream->fd, page.body, page.body_len);
147 if (ib != page.body_len) {
148 tc_log_error(__FILE__, "error while writing page bofy");
149 import_exit(1); /* XXX ugly */
150 }
151 if (verbose_flag & TC_DEBUG)
152 tc_log_msg(__FILE__, "x/a%d: %d + %d written", stream->sno, ih, ib);
153 }
154 }
155
handle_packet(stream_t * stream,ogg_packet * pack,ogg_page * page)156 static void handle_packet(stream_t *stream, ogg_packet *pack, ogg_page *page) {
157 int i, w, hdrlen, end;
158 long long lenbytes;
159 char *sub;
160 char out[100];
161 ogg_int64_t pgp, sst;
162
163 //tc_log_msg(__FILE__, "Going handle 1");
164 if (pack->e_o_s) {
165 stream->eos = 1;
166 pack->e_o_s = 1;
167 }
168
169 if (((double)pack->granulepos * 1000.0 / (double)stream->sample_rate) >
170 highest_ts)
171 highest_ts = (double)pack->granulepos * 1000.0 /
172 (double)stream->sample_rate;
173
174 switch (stream->stype) {
175 case 'v':
176 if (!extraction_requested(xvideo, stream->sno, NOVIDEO))
177 return;
178 break;
179 case 'a':
180 if (!extraction_requested(xaudio, stream->sno, NOAUDIO))
181 return;
182 break;
183 case 't':
184 if (!extraction_requested(xtext, stream->sno, NOTEXT))
185 return;
186 break;
187 }
188
189 hdrlen = (*pack->packet & OGM_PACKET_LEN_BITS01) >> 6;
190 hdrlen |= (*pack->packet & OGM_PACKET_LEN_BITS2) << 1;
191 for (i = 0, lenbytes = 0; i < hdrlen; i++) {
192 lenbytes = lenbytes << 8;
193 lenbytes += *((unsigned char *)pack->packet + hdrlen - i);
194 }
195
196 switch (stream->stype) {
197 case 'v':
198 if (((*pack->packet & 3) == OGM_PACKET_TYPE_HEADER) ||
199 ((*pack->packet & 3) == OGM_PACKET_TYPE_COMMENT))
200 return;
201 i = tc_pwrite(stream->fd, (char *)&pack->packet[hdrlen + 1],
202 pack->bytes - 1 - hdrlen);
203 if (i != pack->bytes - 1 - hdrlen) {
204 tc_log_error(__FILE__, "error while writing data");
205 import_exit(1); /* XXX ugly */
206 }
207 if (verbose_flag & TC_DEBUG)
208 tc_log_msg(__FILE__, "x/v%d: %d written", stream->sno, i);
209 break;
210 case 't':
211 if (((*pack->packet & 3) == OGM_PACKET_TYPE_HEADER) ||
212 ((*pack->packet & 3) == OGM_PACKET_TYPE_COMMENT))
213 return;
214
215 if (xraw) {
216 i = tc_pwrite(stream->fd, (char *)&pack->packet[hdrlen + 1],
217 pack->bytes - 1 - hdrlen);
218 if (i != pack->bytes - 1 - hdrlen) {
219 tc_log_error(__FILE__, "error while writing data");
220 import_exit(1); /* XXX ugly */
221 }
222 if (verbose_flag & TC_DEBUG)
223 tc_log_msg(__FILE__, "x/t%d: %d written", stream->sno, i);
224 return;
225 }
226
227 sub = (char *)&pack->packet[hdrlen + 1];
228 if ((strlen(sub) > 1) || (*sub != ' ')) {
229 sst = (pack->granulepos / stream->sample_rate) * 1000;
230 pgp = sst + lenbytes;
231 tc_snprintf(out,sizeof(out), "%d\r\n%02d:%02d:%02d,%03d --> " \
232 "%02d:%02d:%02d,%03d\r\n", stream->subnr + 1,
233 (int)(sst / 3600000),
234 (int)(sst / 60000) % 60,
235 (int)(sst / 1000) % 60,
236 (int)(sst % 1000),
237 (int)(pgp / 3600000),
238 (int)(pgp / 60000) % 60,
239 (int)(pgp / 1000) % 60,
240 (int)(pgp % 1000));
241 i = tc_pwrite(stream->fd, out, strlen(out));
242 if (i != strlen(out)) {
243 tc_log_error(__FILE__, "error while writing data");
244 import_exit(1); /* XXX ugly */
245 }
246 end = strlen(sub) - 1;
247 while ((end >= 0) && ((sub[end] == '\n') || (sub[end] == '\r'))) {
248 sub[end] = 0;
249 end--;
250 }
251 w = tc_pwrite(stream->fd, sub, strlen(sub));
252 if (i == strlen(sub)) {
253 i += w;
254 } else {
255 tc_log_error(__FILE__, "error while writing data");
256 import_exit(1);
257 }
258 w = tc_pwrite(stream->fd, "\r\n\r\n", 4);
259 if (w == 4) {
260 i += w;
261 } else {
262 tc_log_error(__FILE__, "error while writing data");
263 import_exit(1);
264 }
265 stream->subnr++;
266 if (verbose_flag & TC_DEBUG)
267 tc_log_msg(__FILE__, "x/t%d: %d written", stream->sno, i);
268 }
269 break;
270 case 'a':
271 switch (stream->acodec) {
272 case ACVORBIS:
273 if (xraw) {
274 if (stream->packetno == 0) {
275 i = tc_pwrite(stream->fd, (char *)pack->packet, pack->bytes);
276 if (i != pack->bytes) {
277 tc_log_error(__FILE__, "error while writing data");
278 import_exit(1); /* XXX ugly */
279 }
280 } else {
281 i = tc_pwrite(stream->fd, (char *)&pack->packet[1],
282 pack->bytes - 1);
283 if (i != pack->bytes - 1) {
284 tc_log_error(__FILE__, "error while writing data");
285 import_exit(1); /* XXX ugly */
286 }
287 }
288 if (verbose_flag & TC_DEBUG)
289 tc_log_msg(__FILE__, "x/a%d: %d written", stream->sno, i);
290 return;
291 }
292 stream->max_granulepos = (pack->granulepos > stream->max_granulepos ?
293 pack->granulepos : stream->max_granulepos);
294 if ((stream->packetno == 0) || (stream->packetno == 2)) {
295 ogg_stream_packetin(&stream->outstate, pack);
296 flush_pages(stream, pack);
297 } else {
298 ogg_stream_packetin(&stream->outstate, pack);
299 write_pages(stream, pack);
300 }
301 stream->packetno++;
302 break;
303 default:
304 if (((*pack->packet & 3) == OGM_PACKET_TYPE_HEADER) ||
305 ((*pack->packet & 3) == OGM_PACKET_TYPE_COMMENT))
306 return;
307
308 i = tc_pwrite(stream->fd, pack->packet + 1 + hdrlen,
309 pack->bytes - 1 - hdrlen);
310 if (i != pack->bytes - 1 - hdrlen) {
311 tc_log_error(__FILE__, "error while writing data");
312 import_exit(1); /* XXX ugly */
313 }
314 stream->bwritten += i;
315 if (verbose_flag & TC_DEBUG)
316 tc_log_msg(__FILE__, "x/a%d: %d written", stream->sno, i);
317 break;
318 }
319 break;
320 }
321 }
322
process_ogm(int fdin,int fdout)323 static void process_ogm(int fdin, int fdout)
324 {
325 ogg_sync_state sync;
326 ogg_page page;
327 ogg_packet pack;
328 vorbis_info vi;
329 vorbis_comment vc;
330 char *buf, *new_name;
331 int nread, np, sno;
332 int endofstream = 0;
333 stream_t *stream = NULL;
334
335 ogg_sync_init(&sync);
336 while (1) {
337 np = ogg_sync_pageseek(&sync, &page);
338 if (np < 0) {
339 tc_log_error(__FILE__, "ogg_sync_pageseek failed");
340 return;
341 }
342 if (np == 0) {
343 buf = ogg_sync_buffer(&sync, BLOCK_SIZE);
344 if (!buf) {
345 tc_log_error(__FILE__, "ogg_sync_buffer failed");
346 return;
347 }
348 if ((nread = read(fdin, buf, BLOCK_SIZE)) <= 0) {
349 if (verbose_flag & TC_INFO)
350 tc_log_info(__FILE__, "end of stream 1");
351 return;
352 }
353 ogg_sync_wrote(&sync, nread);
354 continue;
355 }
356
357 if (!ogg_page_bos(&page)) {
358 break;
359 } else {
360 ogg_stream_state sstate;
361 sno = ogg_page_serialno(&page);
362 if (ogg_stream_init(&sstate, sno)) {
363 tc_log_error(__FILE__, "ogg_stream_init failed");
364 return;
365 }
366 ogg_stream_pagein(&sstate, &page);
367 ogg_stream_packetout(&sstate, &pack);
368
369 if ((pack.bytes >= 7) && ! strncmp(&pack.packet[1], "vorbis", 6)) {
370
371 stream = tc_malloc(sizeof(stream_t));
372 if (stream == NULL) {
373 tc_log_error(__FILE__, "malloc failed.");
374 exit(1);
375 }
376
377 memset(stream, 0, sizeof(stream_t));
378 if (verbose_flag & TC_INFO) {
379 vorbis_info_init(&vi);
380 vorbis_comment_init(&vc);
381 if (vorbis_synthesis_headerin(&vi, &vc, &pack) >= 0) {
382 tc_log_info(__FILE__, "(a%d/%d) Vorbis audio (channels %d "
383 "rate %ld)", nastreams + 1, numstreams + 1,
384 vi.channels, vi.rate);
385 stream->sample_rate = vi.rate;
386 } else
387 tc_log_warn(__FILE__, "(a%d/%d) Vorbis audio stream indicated "
388 "but no Vorbis stream header found.",
389 nastreams + 1, numstreams + 1);
390 }
391 stream->serial = sno;
392 stream->acodec = ACVORBIS;
393 stream->sample_rate = -1;
394 stream->sno = nastreams + 1;
395 stream->stype = 'a';
396 ac_memcpy(&stream->instate, &sstate, sizeof(sstate));
397 if (extraction_requested(xaudio, nastreams + 1, NOAUDIO)) {
398 stream->fd = fdout;
399 if (stream->fd == -1) {
400 tc_log_error(__FILE__, "Failed to create \"%s\" (%d, %s).",
401 "new_name", errno, strerror(errno));
402 exit(1);
403 }
404 if (!xraw)
405 ogg_stream_init(&stream->outstate, rand());
406 if (verbose_flag & TC_INFO)
407 tc_log_info(__FILE__, "Extracting a%d to \"%s\".",
408 nastreams + 1, "new_name");
409 do
410 handle_packet(stream, &pack, &page);
411 while (ogg_stream_packetout(&stream->instate, &pack) == 1);
412 }
413 add_stream(stream);
414 nastreams++;
415 numstreams++;
416 } else if ((pack.bytes >= 142) &&
417 !strncmp(&pack.packet[1],"Direct Show Samples embedded in Ogg",
418 35) ) {
419 if ((*(int32_t*)(pack.packet+96) == 0x05589f80) &&
420 (pack.bytes >= 184)) {
421 tc_log_warn(__FILE__, "(v%d/%d) Found old video header. Not "
422 "supported.", nvstreams + 1, numstreams + 1);
423 } else if (*(int32_t*)pack.packet+96 == 0x05589F81) {
424 tc_log_warn(__FILE__, "(a%d/%d) Found old audio header. Not "
425 "supported.", nastreams + 1, numstreams + 1);
426 } else {
427 if (verbose_flag & TC_INFO)
428 tc_log_warn(__FILE__, "OGG stream %d has an old header with an "
429 "unknown type.", numstreams + 1);
430 }
431 } else if (((*pack.packet & OGM_PACKET_TYPE_BITS ) == OGM_PACKET_TYPE_HEADER) &&
432 (pack.bytes >= (int)(sizeof(ogm_stream_header) + 1 - sizeof(int)))) {
433 ogm_stream_header *sth = (ogm_stream_header *)(pack.packet + 1);
434 if (!strncmp(sth->streamtype, "video", 5)) {
435 unsigned long codec;
436 char ccodec[5];
437 strncpy(ccodec, sth->subtype, 4);
438 ccodec[4] = 0;
439 codec = (sth->subtype[0] << 24) +
440 (sth->subtype[1] << 16) + (sth->subtype[2] << 8) + sth->subtype[3];
441 if (verbose_flag & TC_INFO)
442 tc_log_info(__FILE__, "(v%d/%d) fps: %.3f width height: %dx%d "
443 "codec: %p (%s)", nvstreams + 1, numstreams + 1,
444 (double)10000000 / (double)sth->time_unit,
445 sth->sh.video.width, sth->sh.video.height,
446 (void *)codec, ccodec);
447 stream = tc_malloc(sizeof(stream_t));
448 if (stream == NULL) {
449 tc_log_error(__FILE__, "malloc failed.");
450 exit(1);
451 }
452 stream->stype = 'v';
453 stream->serial = sno;
454 stream->sample_rate = (double)10000000 / (double)sth->time_unit;
455 stream->sno = nvstreams + 1;
456 ac_memcpy(&stream->instate, &sstate, sizeof(sstate));
457 if (extraction_requested(xvideo, nvstreams + 1, NOVIDEO)) {
458 stream->fd = fdout;
459
460 if (verbose_flag & TC_INFO)
461 tc_log_info(__FILE__, "Extracting v%d to \"%s\".",
462 nvstreams + 1, "new_name");
463 do {
464 handle_packet(stream, &pack, &page);
465 } while (ogg_stream_packetout(&stream->instate, &pack) == 1);
466 }
467 add_stream(stream);
468 nvstreams++;
469 numstreams++;
470 } else if (!strncmp(sth->streamtype, "audio", 5)) {
471 int codec;
472 char buf[5];
473 ac_memcpy(buf, sth->subtype, 4);
474 buf[4] = 0;
475 codec = strtoul(buf, NULL, 16);
476 if (verbose_flag & TC_INFO) {
477 tc_log_info(__FILE__, "(a%d/%d) codec: %d (0x%04x) (%s), bits per "
478 "sample: %d channels: %hd samples per second: %lld "
479 " avgbytespersec: %hd blockalign: %d",
480 nastreams + 1, numstreams + 1, codec, codec,
481 codec == ACPCM ? "PCM" : codec == 55 ? "MP3" :
482 codec == ACMP3 ? "MP3" :
483 codec == ACAC3 ? "AC3" : "unknown",
484 sth->bits_per_sample, sth->sh.audio.channels,
485 (long long)sth->samples_per_unit,
486 sth->sh.audio.avgbytespersec, sth->sh.audio.blockalign);
487 }
488 stream = tc_malloc(sizeof(stream_t));
489 if (stream == NULL) {
490 tc_log_error(__FILE__, "malloc failed.");
491 exit(1);
492 }
493 stream->sno = nastreams + 1;
494 stream->stype = 'a';
495 stream->sample_rate = sth->samples_per_unit *
496 sth->sh.audio.channels;
497 stream->serial = sno;
498 stream->acodec = codec;
499 ac_memcpy(&stream->instate, &sstate, sizeof(sstate));
500 if (extraction_requested(xaudio, nastreams + 1, NOAUDIO)) {
501
502 /*
503 codec == ACPCM ? "wav" :
504 codec == ACMP3 ? "mp3" :
505 codec == ACAC3 ? "ac3" : "audio");
506 */
507 stream->fd = fdout;
508 if (verbose_flag & TC_INFO)
509 tc_log_info(__FILE__, "Extracting a%d to \"%s\".",
510 nastreams + 1, "new_name");
511 do {
512 handle_packet(stream, &pack, &page);
513 } while (ogg_stream_packetout(&stream->instate, &pack) == 1);
514 }
515 add_stream(stream);
516 nastreams++;
517 numstreams++;
518 } else if (!strncmp(sth->streamtype, "text", 4)) {
519 if (verbose_flag & TC_INFO)
520 tc_log_info(__FILE__, "(t%d/%d) text/subtitle stream",
521 ntstreams + 1, numstreams + 1);
522 stream = tc_malloc(sizeof(stream_t));
523 if (stream == NULL) {
524 tc_log_error(__FILE__, "malloc failed.");
525 exit(1);
526 }
527 stream->sno = ntstreams + 1;
528 stream->stype = 't';
529 stream->sample_rate = (double)10000000 / (double)sth->time_unit;
530 stream->serial = sno;
531 ac_memcpy(&stream->instate, &sstate, sizeof(sstate));
532 if (extraction_requested(xtext, ntstreams + 1, NOTEXT)) {
533 new_name = tc_malloc(strlen(basename) + 20);
534 if (!new_name) {
535 tc_log_error(__FILE__, "Failed to allocate %d bytes.",
536 (int)strlen(basename) + 20);
537 exit(1);
538 }
539 if (!xraw)
540 tc_snprintf(new_name, strlen(basename) + 20, "%s-t%d.srt", basename, ntstreams + 1);
541 else
542 tc_snprintf(new_name, strlen(basename) + 20, "%s-t%d.raw", basename, ntstreams + 1);
543 //stream->fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC,
544 // S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
545 stream->fd = fdout;
546 if (stream->fd == -1) {
547 tc_log_error(__FILE__, "Failed to create \"%s\" (%d, %s).",
548 new_name, errno, strerror(errno));
549 exit(1);
550 }
551 if (verbose_flag & TC_INFO)
552 tc_log_info(__FILE__, "Extracting t%d to \"%s\".",
553 ntstreams + 1, new_name);
554 do
555 handle_packet(stream, &pack, &page);
556 while (ogg_stream_packetout(&stream->instate, &pack) == 1);
557 }
558 add_stream(stream);
559 ntstreams++;
560 numstreams++;
561 } else {
562 tc_log_warn(__FILE__, "(%d) found new header of unknown/"
563 "unsupported type\n", numstreams + 1);
564 }
565
566 } else {
567 tc_log_warn(__FILE__, "OGG stream %d is of an unknown type "
568 "(bad header?)\n", numstreams + 1);
569 }
570 }
571 }
572
573 endofstream = 0;
574 while (!endofstream) {
575 sno = ogg_page_serialno(&page);
576 stream = find_stream(sno);
577 if (stream == NULL) {
578 if (verbose_flag & TC_DEBUG)
579 tc_log_warn(__FILE__, "Encountered packet for an unknown serial "
580 "%d !?\n", sno);
581 } else {
582 if (verbose_flag & TC_DEBUG)
583 tc_log_msg(__FILE__, "%c%d: NEW PAGE", stream->stype, stream->sno);
584
585 ogg_stream_pagein(&stream->instate, &page);
586 while (ogg_stream_packetout(&stream->instate, &pack) == 1)
587 handle_packet(stream, &pack, &page);
588 }
589
590 while (ogg_sync_pageseek(&sync, &page) <= 0) {
591 buf = ogg_sync_buffer(&sync, BLOCK_SIZE);
592 nread = read(fdin, buf, BLOCK_SIZE);
593 if (nread <= 0) {
594 stream = first;
595 while (stream != NULL) {
596 switch (stream->stype) {
597 case 'v':
598 close(stream->fd);
599 break;
600 case 't':
601 if (stream->fd > 0)
602 close(stream->fd);
603 break;
604 case 'a':
605 if ((stream->fd > 0) && !xraw) {
606 switch (stream->acodec) {
607 case ACVORBIS:
608 if (!stream->eos) {
609 pack.b_o_s = 0;
610 pack.e_o_s = 1;
611 pack.packet = NULL;
612 pack.bytes = 0;
613 pack.granulepos = stream->max_granulepos;
614 pack.packetno = stream->packetno;
615 ogg_stream_packetin(&stream->outstate, &pack);
616 }
617 flush_pages(stream, &pack);
618 ogg_stream_clear(&stream->outstate);
619 break;
620 }
621 close(stream->fd);
622 } else if (stream->fd > 0)
623 close(stream->fd);
624 break;
625 }
626 stream = stream->next;
627 }
628 if (verbose_flag & TC_INFO)
629 tc_log_info(__FILE__, "end of stream");
630 endofstream = 1;
631 break;
632 } else
633 ogg_sync_wrote(&sync, nread);
634 }
635 }
636 }
637 #endif /* have OGG */
638
extract_ogm(info_t * ipipe)639 void extract_ogm (info_t *ipipe)
640 {
641 // track
642
643 no[NOTEXT] = 1;
644 no[NOAUDIO] = 0;
645 no[NOVIDEO] = 0;
646 xraw = 1;
647
648 xvideo = tc_zalloc (16); xaudio = tc_zalloc (16); xtext = tc_zalloc (16);
649
650 verbose_flag = ipipe->verbose;
651
652 if (ipipe->select == TC_VIDEO) {
653
654 no[NOAUDIO] = 1;
655 xvideo[0] = (unsigned char)(ipipe->track+1);
656
657 }
658
659 if (ipipe->select == TC_AUDIO) {
660
661 no[NOVIDEO] = 1;
662 xaudio[0] = (unsigned char)(ipipe->track+1);
663
664 // we need !xraw because no tool seems to be able to handle
665 // raw vorbis streams -- tibit
666
667 if (ipipe->codec == TC_CODEC_VORBIS) {
668 xraw = 0;
669 }
670
671 }
672
673 #if (HAVE_OGG && HAVE_VORBIS)
674 process_ogm(ipipe->fd_in, ipipe->fd_out);
675 #else
676 tc_log_error(__FILE__, "No support for Ogg/Vorbis compiled in");
677 import_exit(1);
678 #endif
679 }
680
681
682
683 /* vim: sw=2
684 */
685