101
static int _commentheader_out(vorbis_comment *vc, char *vendor, ogg_packet *op)
102
static int _commentheader_out(vcedit_state *state, ogg_packet *op)
104
vorbis_comment *vc = state->vc;
105
char *vendor = state->vendor;
103
106
oggpack_buffer opb;
105
108
oggpack_writeinit(&opb);
108
oggpack_write(&opb,0x03,8);
109
_v_writestring(&opb,"vorbis", 6);
110
if (state->oggtype == VCEDIT_IS_OGGVORBIS)
113
oggpack_write(&opb,0x03,8);
114
_v_writestring(&opb,"vorbis", 6);
112
118
oggpack_write(&opb,strlen(vendor),32);
119
125
for(i=0;i<vc->comments;i++){
120
126
if(vc->user_comments[i]){
121
127
oggpack_write(&opb,vc->comment_lengths[i],32);
122
_v_writestring(&opb,vc->user_comments[i],
123
vc->comment_lengths[i]);
128
_v_writestring(&opb,vc->user_comments[i],
129
vc->comment_lengths[i]);
125
131
oggpack_write(&opb,0,32);
174
184
buffer = ogg_sync_buffer(s->oy, CHUNKSIZE);
175
185
bytes = s->read(buffer,1, CHUNKSIZE, s->in);
176
186
ogg_sync_wrote(s->oy, bytes);
180
190
if(ogg_page_eos(page))
205
* Next functions pulled straight from libvorbis,
207
static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
209
*buf++=oggpack_read(o,8);
214
* Next functions pulled straight from libvorbis, apart from one change
215
* - disabled the EOP check
217
static int _speex_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb)
220
int vendorlen=oggpack_read(opb,32);
224
vc->vendor=_ogg_calloc(vendorlen+1,1);
225
_v_readstring(opb,vc->vendor,vendorlen);
227
vc->comments=oggpack_read(opb,32);
230
vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
231
vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
232
for (i=0;i<vc->comments;i++){
233
int len=oggpack_read(opb,32);
236
vc->comment_lengths[i]=len;
237
vc->user_comments[i]=_ogg_calloc(len+1,1);
238
_v_readstring(opb,vc->user_comments[i],len);
240
//if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
244
vorbis_comment_clear(vc);
194
248
int vcedit_open(vcedit_state *state, FILE *in)
196
return vcedit_open_callbacks(state, (void *)in,
250
return vcedit_open_callbacks(state, (void *)in,
197
251
(vcedit_read_func)fread, (vcedit_write_func)fwrite);
263
if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) < 0)
265
state->lasterror = _("Ogg bitstream does not contain vorbis data.");
317
// We save the main header first, (it seems speex_packet_to_header munge's it??)
269
318
state->mainlen = header_main.bytes;
270
319
state->mainbuf = malloc(state->mainlen);
271
320
memcpy(state->mainbuf, header_main.packet, header_main.bytes);
274
header = &header_comments;
322
state->oggtype = VCEDIT_IS_UNKNOWN;
323
int headerpackets = 0;
324
if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) == 0)
326
state->oggtype = VCEDIT_IS_OGGVORBIS;
331
// Done after "Ogg test" to avoid to display an error message in function
332
// speex_packet_to_header when the file is not Speex.
333
state->si = malloc(sizeof(SpeexHeader));
334
if((state->si = speex_packet_to_header((char*)(&header_main)->packet,(&header_main)->bytes)))
335
state->oggtype = VCEDIT_IS_SPEEX;
339
if (state->oggtype == VCEDIT_IS_UNKNOWN)
341
state->lasterror = _("Ogg bitstream contains neither speex or vorbis data.");
345
switch (state->oggtype)
347
case VCEDIT_IS_OGGVORBIS:
348
header = &header_comments;
352
case VCEDIT_IS_SPEEX:
353
header = &header_comments;
354
headerpackets = 2 + state->si->extra_headers;
360
while(i<headerpackets)
362
while(i<headerpackets)
277
364
int result = ogg_sync_pageout(state->oy, &og);
278
365
if(result == 0) break; /* Too little data so far */
279
366
else if(result == 1)
281
368
ogg_stream_pagein(state->os, &og);
369
while(i< headerpackets)
284
371
result = ogg_stream_packetout(state->os, header);
285
372
if(result == 0) break;
288
375
state->lasterror = _("Corrupt secondary header.");
291
vorbis_synthesis_headerin(state->vi, state->vc, header);
378
switch (state->oggtype)
294
state->booklen = header->bytes;
295
state->bookbuf = malloc(state->booklen);
296
memcpy(state->bookbuf, header->packet,
380
case VCEDIT_IS_OGGVORBIS:
381
vorbis_synthesis_headerin(state->vi, state->vc, header);
384
// 0 packet was the vorbis header
386
header = &header_codebooks;
389
state->booklen = header->bytes;
390
state->bookbuf = malloc(state->booklen);
391
memcpy(state->bookbuf, header->packet,
396
case VCEDIT_IS_SPEEX:
399
// 0 packet was the speex header
401
oggpack_readinit(&opb,header->packet,header->bytes);
402
_speex_unpack_comment(state->vc,&opb);
405
state->lasterror = _("Need to save extra headers - TODO!!");
300
header = &header_codebooks;
357
467
ogg_stream_init(&streamout, state->serial);
359
_commentheader_out(state->vc, state->vendor, &header_comments);
361
/* 2002/10/22 - new code here for padded headers */
362
//header_comments.packet = realloc(header_comments.packet, header_comments.bytes + 1000);
363
//header_comments.bytes += 1000;
364
/* end of new code */
469
_commentheader_out(state, &header_comments);
366
471
ogg_stream_packetin(&streamout, &header_main);
367
472
ogg_stream_packetin(&streamout, &header_comments);
368
ogg_stream_packetin(&streamout, &header_codebooks);
474
if (state->oggtype != VCEDIT_IS_SPEEX)
475
ogg_stream_packetin(&streamout, &header_codebooks);
370
477
while((result = ogg_stream_flush(&streamout, &ogout)))
372
479
if(state->write(ogout.header,1,ogout.header_len, out) !=
373
480
(size_t) ogout.header_len)
375
if(state->write(ogout.body,1,ogout.body_len, out) !=
482
if(state->write(ogout.body,1,ogout.body_len, out) !=
376
483
(size_t) ogout.body_len)
380
487
while(_fetch_next_packet(state, &op, &ogin))
383
size = _blocksize(state, &op);
388
491
if(ogg_stream_flush(&streamout, &ogout))
390
if(state->write(ogout.header,1,ogout.header_len,
493
if(state->write(ogout.header,1,ogout.header_len,
391
494
out) != (size_t) ogout.header_len)
393
if(state->write(ogout.body,1,ogout.body_len,
496
if(state->write(ogout.body,1,ogout.body_len,
394
497
out) != (size_t) ogout.body_len)
400
503
if(ogg_stream_pageout(&streamout, &ogout))
402
if(state->write(ogout.header,1,ogout.header_len,
505
if(state->write(ogout.header,1,ogout.header_len,
403
506
out) != (size_t) ogout.header_len)
405
if(state->write(ogout.body,1,ogout.body_len,
508
if(state->write(ogout.body,1,ogout.body_len,
406
509
out) != (size_t) ogout.body_len)
411
514
needflush=needout=0;
413
if(op.granulepos == -1)
415
op.granulepos = granpos;
516
if (state->oggtype == VCEDIT_IS_OGGVORBIS)
519
size = _blocksize(state, &op);
522
if(op.granulepos == -1)
524
op.granulepos = granpos;
525
ogg_stream_packetin(&streamout, &op);
527
else /* granulepos is set, validly. Use it, and force a flush to
528
account for shortened blocks (vcut) when appropriate */
530
if(granpos > op.granulepos)
532
granpos = op.granulepos;
533
ogg_stream_packetin(&streamout, &op);
538
ogg_stream_packetin(&streamout, &op);
543
/* Don't know about granulepos for speex, will just assume the original
544
was appropriate. Not sure about the flushing?? */
545
else if (state->oggtype == VCEDIT_IS_SPEEX)
416
547
ogg_stream_packetin(&streamout, &op);
418
else /* granulepos is set, validly. Use it, and force a flush to
419
account for shortened blocks (vcut) when appropriate */
421
if(granpos > op.granulepos)
423
granpos = op.granulepos;
424
ogg_stream_packetin(&streamout, &op);
429
ogg_stream_packetin(&streamout, &op);
435
552
streamout.e_o_s = 1;
436
553
while(ogg_stream_flush(&streamout, &ogout))
438
if(state->write(ogout.header,1,ogout.header_len,
555
if(state->write(ogout.header,1,ogout.header_len,
439
556
out) != (size_t) ogout.header_len)
441
if(state->write(ogout.body,1,ogout.body_len,
558
if(state->write(ogout.body,1,ogout.body_len,
442
559
out) != (size_t) ogout.body_len)
467
584
state->lasterror = _("Corrupt or missing data, continuing...");
470
/* Don't bother going through the rest, we can just
587
/* Don't bother going through the rest, we can just
471
588
* write the page out now */
472
if(state->write(ogout.header,1,ogout.header_len,
589
if(state->write(ogout.header,1,ogout.header_len,
473
590
out) != (size_t) ogout.header_len) {
482
599
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
483
600
bytes = state->read(buffer,1, CHUNKSIZE, state->in);
484
601
ogg_sync_wrote(state->oy, bytes);
487
604
state->eosin = 1;
494
611
ogg_stream_clear(&streamout);
496
/* We don't ogg_packet_clear() this, because the memory was allocated in
497
_commentheader_out(), so we mirror that here */
498
_ogg_free(header_comments.packet);
612
ogg_packet_clear(&header_comments);
500
614
free(state->mainbuf);
501
615
free(state->bookbuf);