r955: Fix the Diffkey icon.
[cinelerra_cv.git] / quicktime / vorbis.c
blobf2ab53cbce78a55c639839c8bcaf0bf13db3c7f8
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "qtvorbis.h"
4 #include <string.h>
5 #include "vorbis/vorbisenc.h"
7 // Attempts to read more samples than this will crash
8 #define OUTPUT_ALLOCATION 0x100000
9 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
11 typedef struct
13 int max_bitrate;
14 int nominal_bitrate;
15 int min_bitrate;
16 int use_vbr;
17 int encode_initialized;
18 ogg_stream_state enc_os;
19 ogg_page enc_og;
20 ogg_packet enc_op;
21 vorbis_info enc_vi;
22 vorbis_comment enc_vc;
23 vorbis_dsp_state enc_vd;
24 vorbis_block enc_vb;
25 // Number of samples written to disk
26 int encoded_samples;
27 // Number of bytes written to disk
28 int64_t encoded_bytes;
31 // Number of samples encoded into the chunk
32 int next_chunk_size;
36 ogg_sync_state dec_oy; /* sync and verify incoming physical bitstream */
37 ogg_stream_state dec_os; /* take physical pages, weld into a logical
38 stream of packets */
39 ogg_page dec_og; /* one Ogg bitstream page. Vorbis packets are inside */
40 ogg_packet dec_op; /* one raw packet of data for decode */
42 vorbis_info dec_vi; /* struct that stores all the static vorbis bitstream
43 settings */
44 vorbis_comment dec_vc; /* struct that stores all the bitstream user comments */
45 vorbis_dsp_state dec_vd; /* central working state for the packet->PCM decoder */
46 vorbis_block dec_vb; /* local working space for packet->PCM decode */
48 unsigned int dec_current_serialno;
49 int decode_initialized;
50 float **output;
52 // Number of last sample relative to file
53 int64_t output_position;
54 // Number of last sample relative to output buffer
55 long output_end;
56 // Number of samples in output buffer
57 long output_size;
58 // Number of samples allocated in output buffer
59 long output_allocated;
60 // Current reading position in file
61 int64_t chunk;
62 // Number of samples decoded in the current chunk
63 int chunk_samples;
64 } quicktime_vorbis_codec_t;
67 /* =================================== public for vorbis */
69 static int delete_codec(quicktime_audio_map_t *atrack)
71 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
72 int i;
74 if(codec->encode_initialized)
76 ogg_stream_clear(&codec->enc_os);
77 vorbis_block_clear(&codec->enc_vb);
78 vorbis_dsp_clear(&codec->enc_vd);
79 vorbis_comment_clear(&codec->enc_vc);
80 vorbis_info_clear(&codec->enc_vi);
83 if(codec->decode_initialized)
85 if(codec->output)
87 for(i = 0; i < atrack->channels; i++)
88 free(codec->output[i]);
90 free(codec->output);
93 ogg_stream_clear(&codec->dec_os);
94 vorbis_block_clear(&codec->dec_vb);
95 vorbis_dsp_clear(&codec->dec_vd);
96 vorbis_comment_clear(&codec->dec_vc);
97 vorbis_info_clear(&codec->dec_vi);
100 free(codec);
101 return 0;
108 // Buffer fragment should be bigger then largest page header so
109 // all lacing bytes can be decoded.
110 #define BUFFER_FRAGMENT 4096
112 // Calculate chunk length from OggS headers. This is the worst case
113 // but it's better not to assume libogg is going to do anything for us.
115 #define SEGMENT_OFFSET 0x1a
116 #define LACE_OFFSET 0x1b
117 static int chunk_len(quicktime_t *file, int64_t offset, int64_t next_chunk)
119 int result = 0;
120 unsigned char buffer[BUFFER_FRAGMENT];
121 int accum = 0;
122 int segment_count = 0;
123 int segment_size = 0;
124 int lace_size = 0;
125 int page_size = 0;
126 int i, j;
128 while(offset < next_chunk)
130 quicktime_set_position(file, offset);
131 result = !quicktime_read_data(file, buffer, BUFFER_FRAGMENT);
133 if(result)
135 return accum;
138 if(memcmp(buffer, "OggS", 4))
140 return accum;
142 else
146 // Decode size of OggS page
147 segment_count = buffer[SEGMENT_OFFSET];
149 // Decode one segment at a time
150 i = LACE_OFFSET;
151 page_size = 0;
152 while(segment_count > 0)
154 page_size += buffer[i++];
155 segment_count--;
157 accum += i + page_size;
158 offset += i + page_size;
162 return accum;
166 // Calculates the chunk size based on ogg pages.
167 #define READ_CHUNK(chunk) \
169 int64_t offset1 = quicktime_chunk_to_offset(file, trak, (chunk)); \
170 int64_t offset2 = quicktime_chunk_to_offset(file, trak, (chunk) + 1); \
171 int size = 0; \
172 if(offset2 == offset1) \
173 result = 1; \
174 else \
176 size = chunk_len(file, offset1, \
177 offset2 > offset1 ? offset2 : offset1 + 0xfffff); \
179 buffer = ogg_sync_buffer(&codec->dec_oy, size); \
180 quicktime_set_position(file, offset1); \
181 result = !quicktime_read_data(file, buffer, size); \
182 ogg_sync_wrote(&codec->dec_oy, size); \
184 /* printf("READ_CHUNK size=%d\n", size); */ \
185 /* printf("%llx %x: ", quicktime_chunk_to_offset(file, trak, (chunk)), size); */ \
186 /* for(i = 0; i < 16; i++) */ \
187 /* printf("%02x ", buffer[i]); */ \
188 /* printf("result=%d\n", result); */ \
194 static int decode(quicktime_t *file,
195 int16_t *output_i,
196 float *output_f,
197 long samples,
198 int track,
199 int channel)
201 int result = 0;
202 int bytes;
203 int i, j;
204 quicktime_audio_map_t *track_map = &(file->atracks[track]);
205 quicktime_trak_t *trak = track_map->track;
206 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
207 long current_position = track_map->current_position;
208 long end_position = current_position + samples;
209 unsigned char *buffer;
210 // End of data in ogg buffer
211 int eos = 0;
212 // End of file
213 int eof = 0;
214 float *pcm;
215 int have_chunk = 0;
218 if(samples > OUTPUT_ALLOCATION)
219 printf("vorbis.c decode: can't read more than %p samples at a time.\n", OUTPUT_ALLOCATION);
223 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
224 if(output_f) bzero(output_f, sizeof(float) * samples);
232 // Seeked outside output buffer's range or not initialized: restart
233 if(current_position < codec->output_position - codec->output_size ||
234 current_position > codec->output_position ||
235 !codec->decode_initialized)
238 quicktime_chunk_of_sample(&codec->output_position,
239 &codec->chunk,
240 trak,
241 current_position);
242 // We know the first ogg packet in the chunk has a pcm_offset from the encoding.
244 codec->output_size = 0;
245 codec->output_end = 0;
246 codec->chunk_samples = 0;
251 // Initialize and load initial buffer for decoding
252 if(!codec->decode_initialized)
254 int init_chunk = 1;
255 codec->decode_initialized = 1;
257 codec->output = malloc(sizeof(float*) * track_map->channels);
258 for(i = 0; i < track_map->channels; i++)
260 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
263 codec->output_allocated = OUTPUT_ALLOCATION;
265 ogg_sync_init(&codec->dec_oy); /* Now we can read pages */
270 READ_CHUNK(init_chunk);
271 init_chunk++;
273 if(ogg_sync_pageout(&codec->dec_oy, &codec->dec_og)!=1)
275 fprintf(stderr, "decode: ogg_sync_pageout: Must not be Vorbis data\n");
276 return 1;
280 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
281 vorbis_info_init(&codec->dec_vi);
282 vorbis_comment_init(&codec->dec_vc);
284 if(ogg_stream_pagein(&codec->dec_os, &codec->dec_og) < 0)
286 fprintf(stderr,"decode: ogg_stream_pagein: stream version mismatch perhaps.\n");
287 return 1;
290 if(ogg_stream_packetout(&codec->dec_os, &codec->dec_op) != 1)
292 fprintf(stderr, "decode: ogg_stream_packetout: Must not be Vorbis data\n");
293 return 1;
296 if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op) < 0)
298 fprintf(stderr, "decode: vorbis_synthesis_headerin: not a vorbis header\n");
299 return 1;
303 i = 0;
304 while(i < 2)
306 while(i < 2)
308 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
309 if(result == 0) break;
311 if(result == 1)
313 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
315 while(i < 2)
317 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
319 if(result == 0) break;
321 if(result < 0)
323 fprintf(stderr, "decode: ogg_stream_packetout: corrupt secondary header\n");
324 return 1;
327 vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op);
328 i++;
337 if(i < 2)
339 READ_CHUNK(init_chunk);
340 init_chunk++;
343 // Header should never span more than one chunk so assume it's done here
346 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
347 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
349 // Also the first chunk needed in decoding so don't reread after this.
350 if(codec->chunk == init_chunk - 1)
352 have_chunk = 1;
353 codec->chunk++;
360 // Don't already have initial chunk from header
361 if(!have_chunk)
363 // Get initial chunk for decoding at new location
364 // From vorbisfile.c
365 /* clear out decoding machine state */
366 ogg_stream_clear(&codec->dec_os);
367 vorbis_dsp_clear(&codec->dec_vd);
368 vorbis_block_clear(&codec->dec_vb);
369 ogg_sync_reset(&codec->dec_oy);
371 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
372 ogg_sync_init(&codec->dec_oy);
373 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
374 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
377 READ_CHUNK(codec->chunk);
378 codec->chunk++;
379 have_chunk = 1;
383 // Assume the chunk exists by now and rely on libogg to say if it's out of
384 // data.
385 have_chunk = 1;
397 // Read chunks until output buffer is on or after end_position
398 result = 0;
399 while(codec->output_position < end_position)
403 // Read chunk to decode if it hasn't been read yet.
404 if(!have_chunk)
406 codec->chunk_samples = 0;
408 READ_CHUNK(codec->chunk);
409 if(result) break;
410 codec->chunk++;
413 eos = 0;
414 while(!eos)
416 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
424 // Need more data from chunk
425 if(result == 0)
427 // End of chunk
428 eos = 1;
430 else
431 // This stage checks for OggS and a checksum error.
432 // It doesn't tell if it's the end of a chunk. Need to manually parse OggS
433 // pages to figure out how big the chunk is.
434 if(result < 0)
436 //printf("ogg_sync_pageout=-1\n");
439 else
441 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
445 while(!eos)
447 //printf("decode 7\n");
448 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
450 //printf("decode 8 %d\n", result);
451 if(result == 0)
453 //printf("ogg_stream_packetout=0\n");
454 // End of page
455 eos = 1;
457 else
458 // This stage doesn't check for OggS.
459 if(result < 0)
461 //printf("ogg_stream_packetout=-1\n");
463 else
465 float **pcm;
473 if(vorbis_synthesis(&codec->dec_vb, &codec->dec_op) == 0)
475 vorbis_synthesis_blockin(&codec->dec_vd,
476 &codec->dec_vb);
480 while((result = vorbis_synthesis_pcmout(&codec->dec_vd, &pcm)) > 0)
482 //printf("vorbis_synthesis_pcmout=%x\n", result);
483 for(i = 0; i < track_map->channels; i++)
485 float *output_channel = codec->output[i];
486 float *input_channel = pcm[i];
487 int k = codec->output_end;
489 for(j = 0; j < result; j++)
491 output_channel[k++] = input_channel[j];
492 if(k >= codec->output_allocated)
493 k = 0;
496 if(i == track_map->channels - 1)
497 codec->output_end = k;
499 //printf("codec->output_end = %d\n", codec->output_end);
501 codec->output_position += result;
502 codec->output_size += result;
503 codec->chunk_samples += result;
504 if(codec->output_size > codec->output_allocated)
505 codec->output_size = codec->output_allocated;
506 vorbis_synthesis_read(&codec->dec_vd, result);
509 //printf("decode 11\n");
512 // Reset end of page so it isn't interpreted as an end of chunk
513 eos = 0;
518 // Next chunk
519 if(eos)
521 //printf("decode 12 got=%x\n", codec->chunk_samples);
522 have_chunk = 0;
527 // Fill silence
528 while(codec->output_position < end_position)
530 for(i = 0; i < track_map->channels; i++)
531 codec->output[i][codec->output_end] = 0;
533 codec->output_end++;
534 if(codec->output_end >= codec->output_allocated)
535 codec->output_end = 0;
536 codec->output_position++;
538 //printf("decode 15\n");
541 //printf("decode 2 codec->output_position=%lld codec->output_end=%d codec->output_size=%d\n",
542 // codec->output_position, codec->output_end, codec->output_size);
544 current_position = track_map->current_position;
545 i = codec->output_end - (codec->output_position - current_position);
546 j = 0;
547 while(i < 0) i += codec->output_allocated;
548 pcm = codec->output[channel];
550 if(output_i)
552 for( ; j < samples; j++)
554 int sample = pcm[i] * 32767;
555 CLAMP(sample, -32768, 32767);
556 output_i[j] = sample;
558 i++;
559 if(i >= codec->output_allocated) i = 0;
562 else
563 if(output_f)
565 for( ; j < samples; j++)
567 output_f[j] = pcm[i];
568 i++;
569 if(i >= codec->output_allocated) i = 0;
572 //printf("decode 16\n");
574 return 0;
596 #define FLUSH_OGG1 \
597 while(1) \
599 int eos = !ogg_stream_flush(&codec->enc_os, &codec->enc_og); \
600 if(eos) break; \
602 if(!chunk_started) \
604 chunk_started = 1; \
605 quicktime_write_chunk_header(file, trak, &chunk_atom); \
608 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
609 size += codec->enc_og.header_len; \
611 if(!result) \
613 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
614 size += codec->enc_og.body_len; \
618 if(!result) break; \
623 #define FLUSH_OGG2 \
624 while(vorbis_analysis_blockout(&codec->enc_vd, &codec->enc_vb) == 1) \
626 vorbis_analysis(&codec->enc_vb, &codec->enc_op); \
627 vorbis_bitrate_addblock(&codec->enc_vb); \
628 while(vorbis_bitrate_flushpacket(&codec->enc_vd, &codec->enc_op)) \
630 ogg_stream_packetin(&codec->enc_os, &codec->enc_op); \
632 while(!result) \
634 if(!ogg_stream_pageout(&codec->enc_os, &codec->enc_og)) break; \
637 if(!chunk_started) \
639 chunk_started = 1; \
640 quicktime_write_chunk_header(file, trak, &chunk_atom); \
642 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
643 size += codec->enc_og.header_len; \
645 if(!result) \
647 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
648 size += codec->enc_og.body_len; \
651 if(ogg_page_eos(&codec->enc_og)) break; \
657 static int encode(quicktime_t *file,
658 int16_t **input_i,
659 float **input_f,
660 int track,
661 long samples)
663 int result = 0;
664 int64_t offset = quicktime_position(file);
665 quicktime_audio_map_t *track_map = &(file->atracks[track]);
666 quicktime_trak_t *trak = track_map->track;
667 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
668 int samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
669 float **output;
670 int size = 0;
671 int chunk_started = 0;
672 quicktime_atom_t chunk_atom;
675 if(samplerate < 32000)
677 printf("encode: sample rate %d not supported.\n", samplerate);
678 return 1;
685 if(!codec->encode_initialized)
687 ogg_packet header;
688 ogg_packet header_comm;
689 ogg_packet header_code;
692 codec->encode_initialized = 1;
693 if(file->use_avi)
694 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
695 vorbis_info_init(&codec->enc_vi);
697 if(codec->use_vbr)
699 result = vorbis_encode_setup_managed(&codec->enc_vi,
700 track_map->channels,
701 samplerate,
702 codec->max_bitrate,
703 codec->nominal_bitrate,
704 codec->min_bitrate);
705 result |= vorbis_encode_ctl(&codec->enc_vi, OV_ECTL_RATEMANAGE_AVG, NULL);
706 result |= vorbis_encode_setup_init(&codec->enc_vi);
708 else
710 vorbis_encode_init(&codec->enc_vi,
711 track_map->channels,
712 samplerate,
713 codec->max_bitrate,
714 codec->nominal_bitrate,
715 codec->min_bitrate);
719 vorbis_comment_init(&codec->enc_vc);
720 vorbis_analysis_init(&codec->enc_vd, &codec->enc_vi);
721 vorbis_block_init(&codec->enc_vd, &codec->enc_vb);
722 srand(time(NULL));
723 ogg_stream_init(&codec->enc_os, rand());
726 vorbis_analysis_headerout(&codec->enc_vd,
727 &codec->enc_vc,
728 &header,
729 &header_comm,
730 &header_code);
732 ogg_stream_packetin(&codec->enc_os, &header);
733 ogg_stream_packetin(&codec->enc_os, &header_comm);
734 ogg_stream_packetin(&codec->enc_os, &header_code);
736 FLUSH_OGG1
739 output = vorbis_analysis_buffer(&codec->enc_vd, samples);
741 if(input_i)
743 int i, j;
744 for(i = 0; i < track_map->channels; i++)
746 for(j = 0; j < samples; j++)
748 output[i][j] = (float)input_i[i][j] / (float)32768;
752 else
753 if(input_f)
755 int i;
756 for(i = 0; i < track_map->channels; i++)
758 memcpy(output[i], input_f[i], sizeof(float) * samples);
762 vorbis_analysis_wrote(&codec->enc_vd, samples);
764 FLUSH_OGG2
766 codec->next_chunk_size += samples;
768 // Wrote a chunk.
769 if(chunk_started)
771 int new_encoded_samples = codec->enc_vd.granulepos;
772 // granulepos is meaningless for fixed bitrate
773 if(!codec->use_vbr)
775 codec->encoded_bytes += quicktime_position(file) - offset;
776 new_encoded_samples = codec->encoded_bytes *
777 (int64_t)8 *
778 (int64_t)samplerate /
779 (int64_t)codec->nominal_bitrate;
781 quicktime_write_chunk_footer(file,
782 trak,
783 track_map->current_chunk,
784 &chunk_atom,
785 new_encoded_samples - codec->encoded_samples);
786 track_map->current_chunk++;
787 codec->next_chunk_size = 0;
788 codec->encoded_samples = new_encoded_samples;
791 return result;
797 static int set_parameter(quicktime_t *file,
798 int track,
799 char *key,
800 void *value)
802 quicktime_audio_map_t *atrack = &(file->atracks[track]);
803 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
806 if(!strcasecmp(key, "vorbis_vbr"))
807 codec->use_vbr = *(int*)value;
808 else
809 if(!strcasecmp(key, "vorbis_bitrate"))
810 codec->nominal_bitrate = *(int*)value;
811 else
812 if(!strcasecmp(key, "vorbis_max_bitrate"))
813 codec->max_bitrate = *(int*)value;
814 else
815 if(!strcasecmp(key, "vorbis_min_bitrate"))
816 codec->min_bitrate = *(int*)value;
817 return 0;
821 static void flush(quicktime_t *file, int track)
823 quicktime_audio_map_t *track_map = &(file->atracks[track]);
824 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
825 if(codec->encode_initialized)
827 int result = 0;
828 int size = 0;
829 int64_t offset = quicktime_position(file);
830 long output_position = codec->enc_vd.granulepos;
831 int chunk_started = 0;
832 quicktime_trak_t *trak = track_map->track;
833 int sample_rate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
834 quicktime_atom_t chunk_atom;
836 vorbis_analysis_wrote(&codec->enc_vd,0);
838 FLUSH_OGG2
840 if(chunk_started)
842 int new_encoded_samples = codec->enc_vd.granulepos;
843 if(!codec->use_vbr)
845 codec->encoded_bytes += quicktime_position(file) - offset;
846 new_encoded_samples = codec->encoded_bytes *
847 (int64_t)8 *
848 (int64_t)sample_rate /
849 (int64_t)codec->nominal_bitrate;
851 quicktime_write_chunk_footer(file,
852 trak,
853 track_map->current_chunk,
854 &chunk_atom,
855 new_encoded_samples - codec->encoded_samples);
856 track_map->current_chunk++;
857 codec->next_chunk_size = 0;
862 void quicktime_init_codec_vorbis(quicktime_audio_map_t *atrack)
864 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
865 quicktime_vorbis_codec_t *codec;
867 /* Init public items */
868 codec_base->priv = calloc(1, sizeof(quicktime_vorbis_codec_t));
869 codec_base->delete_acodec = delete_codec;
870 codec_base->decode_audio = decode;
871 codec_base->encode_audio = encode;
872 codec_base->set_parameter = set_parameter;
873 codec_base->flush = flush;
874 codec_base->fourcc = QUICKTIME_VORBIS;
875 codec_base->title = "OGG Vorbis";
876 codec_base->desc = "OGG Vorbis for video. (Not standardized)";
878 codec = codec_base->priv;
879 codec->nominal_bitrate = 128000;
880 codec->max_bitrate = -1;
881 codec->min_bitrate = -1;