r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / vorbis.c
blob4d877707236248a83f3fc6054fef92bf2525438d
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "qtvorbis.h"
4 #include "vorbis/vorbisenc.h"
6 // Attempts to read more samples than this will crash
7 #define OUTPUT_ALLOCATION 0x100000
8 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
10 typedef struct
12 int max_bitrate;
13 int nominal_bitrate;
14 int min_bitrate;
15 int use_vbr;
16 int encode_initialized;
17 ogg_stream_state enc_os;
18 ogg_page enc_og;
19 ogg_packet enc_op;
20 vorbis_info enc_vi;
21 vorbis_comment enc_vc;
22 vorbis_dsp_state enc_vd;
23 vorbis_block enc_vb;
24 // Number of samples written to disk
25 int encoded_samples;
29 // Number of samples encoded into the chunk
30 int next_chunk_size;
34 ogg_sync_state dec_oy; /* sync and verify incoming physical bitstream */
35 ogg_stream_state dec_os; /* take physical pages, weld into a logical
36 stream of packets */
37 ogg_page dec_og; /* one Ogg bitstream page. Vorbis packets are inside */
38 ogg_packet dec_op; /* one raw packet of data for decode */
40 vorbis_info dec_vi; /* struct that stores all the static vorbis bitstream
41 settings */
42 vorbis_comment dec_vc; /* struct that stores all the bitstream user comments */
43 vorbis_dsp_state dec_vd; /* central working state for the packet->PCM decoder */
44 vorbis_block dec_vb; /* local working space for packet->PCM decode */
46 unsigned int dec_current_serialno;
47 int decode_initialized;
48 float **output;
50 // Number of last sample relative to file
51 int64_t output_position;
52 // Number of last sample relative to output buffer
53 long output_end;
54 // Number of samples in output buffer
55 long output_size;
56 // Number of samples allocated in output buffer
57 long output_allocated;
58 // Current reading position in file
59 int64_t chunk;
60 // Number of samples decoded in the current chunk
61 int chunk_samples;
62 } quicktime_vorbis_codec_t;
65 /* =================================== public for vorbis */
67 static int delete_codec(quicktime_audio_map_t *atrack)
69 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
70 int i;
72 if(codec->encode_initialized)
74 ogg_stream_clear(&codec->enc_os);
75 vorbis_block_clear(&codec->enc_vb);
76 vorbis_dsp_clear(&codec->enc_vd);
77 vorbis_comment_clear(&codec->enc_vc);
78 vorbis_info_clear(&codec->enc_vi);
81 if(codec->decode_initialized)
83 if(codec->output)
85 for(i = 0; i < atrack->channels; i++)
86 free(codec->output[i]);
88 free(codec->output);
91 ogg_stream_clear(&codec->dec_os);
92 vorbis_block_clear(&codec->dec_vb);
93 vorbis_dsp_clear(&codec->dec_vd);
94 vorbis_comment_clear(&codec->dec_vc);
95 vorbis_info_clear(&codec->dec_vi);
98 free(codec);
99 return 0;
106 // Buffer fragment should be bigger then largest page header so
107 // all lacing bytes can be decoded.
108 #define BUFFER_FRAGMENT 4096
110 // Calculate chunk length from OggS headers. This is the worst case
111 // but it's better not to assume libogg is going to do anything for us.
113 #define SEGMENT_OFFSET 0x1a
114 #define LACE_OFFSET 0x1b
115 static int chunk_len(quicktime_t *file, int64_t offset, int64_t next_chunk)
117 int result = 0;
118 unsigned char buffer[BUFFER_FRAGMENT];
119 int accum = 0;
120 int segment_count = 0;
121 int segment_size = 0;
122 int lace_size = 0;
123 int page_size = 0;
124 int i, j;
126 while(offset < next_chunk)
128 quicktime_set_position(file, offset);
129 result = !quicktime_read_data(file, buffer, BUFFER_FRAGMENT);
131 if(result)
133 return accum;
136 if(memcmp(buffer, "OggS", 4))
138 return accum;
140 else
144 // Decode size of OggS page
145 segment_count = buffer[SEGMENT_OFFSET];
147 // Decode one segment at a time
148 i = LACE_OFFSET;
149 page_size = 0;
150 while(segment_count > 0)
152 page_size += buffer[i++];
153 segment_count--;
155 accum += i + page_size;
156 offset += i + page_size;
160 return accum;
164 // Calculates the chunk size based on ogg pages.
165 #define READ_CHUNK(chunk) \
167 int64_t offset1 = quicktime_chunk_to_offset(file, trak, (chunk)); \
168 int64_t offset2 = quicktime_chunk_to_offset(file, trak, (chunk) + 1); \
169 int size = 0; \
170 if(offset2 == offset1) \
171 result = 1; \
172 else \
174 size = chunk_len(file, offset1, \
175 offset2 > offset1 ? offset2 : offset1 + 0xfffff); \
177 buffer = ogg_sync_buffer(&codec->dec_oy, size); \
178 quicktime_set_position(file, offset1); \
179 result = !quicktime_read_data(file, buffer, size); \
180 ogg_sync_wrote(&codec->dec_oy, size); \
182 /* printf("READ_CHUNK size=%d\n", size); */ \
183 /* printf("%llx %x: ", quicktime_chunk_to_offset(file, trak, (chunk)), size); */ \
184 /* for(i = 0; i < 16; i++) */ \
185 /* printf("%02x ", buffer[i]); */ \
186 /* printf("result=%d\n", result); */ \
192 static int decode(quicktime_t *file,
193 int16_t *output_i,
194 float *output_f,
195 long samples,
196 int track,
197 int channel)
199 int result = 0;
200 int bytes;
201 int i, j;
202 quicktime_audio_map_t *track_map = &(file->atracks[track]);
203 quicktime_trak_t *trak = track_map->track;
204 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
205 long current_position = track_map->current_position;
206 long end_position = current_position + samples;
207 unsigned char *buffer;
208 // End of data in ogg buffer
209 int eos = 0;
210 // End of file
211 int eof = 0;
212 float *pcm;
213 int have_chunk = 0;
216 if(samples > OUTPUT_ALLOCATION)
217 printf("vorbis.c decode: can't read more than %p samples at a time.\n", OUTPUT_ALLOCATION);
221 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
222 if(output_f) bzero(output_f, sizeof(float) * samples);
230 // Seeked outside output buffer's range or not initialized: restart
231 if(current_position < codec->output_position - codec->output_size ||
232 current_position > codec->output_position ||
233 !codec->decode_initialized)
236 quicktime_chunk_of_sample(&codec->output_position,
237 &codec->chunk,
238 trak,
239 current_position);
240 // We know the first ogg packet in the chunk has a pcm_offset from the encoding.
242 codec->output_size = 0;
243 codec->output_end = 0;
244 codec->chunk_samples = 0;
249 // Initialize and load initial buffer for decoding
250 if(!codec->decode_initialized)
252 int init_chunk = 1;
253 codec->decode_initialized = 1;
255 codec->output = malloc(sizeof(float*) * track_map->channels);
256 for(i = 0; i < track_map->channels; i++)
258 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
261 codec->output_allocated = OUTPUT_ALLOCATION;
263 ogg_sync_init(&codec->dec_oy); /* Now we can read pages */
268 READ_CHUNK(init_chunk);
269 init_chunk++;
271 if(ogg_sync_pageout(&codec->dec_oy, &codec->dec_og)!=1)
273 fprintf(stderr, "decode: ogg_sync_pageout: Must not be Vorbis data\n");
274 return 1;
278 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
279 vorbis_info_init(&codec->dec_vi);
280 vorbis_comment_init(&codec->dec_vc);
282 if(ogg_stream_pagein(&codec->dec_os, &codec->dec_og) < 0)
284 fprintf(stderr,"decode: ogg_stream_pagein: stream version mismatch perhaps.\n");
285 return 1;
288 if(ogg_stream_packetout(&codec->dec_os, &codec->dec_op) != 1)
290 fprintf(stderr, "decode: ogg_stream_packetout: Must not be Vorbis data\n");
291 return 1;
294 if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op) < 0)
296 fprintf(stderr, "decode: vorbis_synthesis_headerin: not a vorbis header\n");
297 return 1;
301 i = 0;
302 while(i < 2)
304 while(i < 2)
306 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
307 if(result == 0) break;
309 if(result == 1)
311 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
313 while(i < 2)
315 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
317 if(result == 0) break;
319 if(result < 0)
321 fprintf(stderr, "decode: ogg_stream_packetout: corrupt secondary header\n");
322 return 1;
325 vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op);
326 i++;
335 if(i < 2)
337 READ_CHUNK(init_chunk);
338 init_chunk++;
341 // Header should never span more than one chunk so assume it's done here
344 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
345 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
347 // Also the first chunk needed in decoding so don't reread after this.
348 if(codec->chunk == init_chunk - 1)
350 have_chunk = 1;
351 codec->chunk++;
358 // Don't already have initial chunk from header
359 if(!have_chunk)
361 // Get initial chunk for decoding at new location
362 // From vorbisfile.c
363 /* clear out decoding machine state */
364 ogg_stream_clear(&codec->dec_os);
365 vorbis_dsp_clear(&codec->dec_vd);
366 vorbis_block_clear(&codec->dec_vb);
367 ogg_sync_reset(&codec->dec_oy);
369 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
370 ogg_sync_init(&codec->dec_oy);
371 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
372 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
375 READ_CHUNK(codec->chunk);
376 codec->chunk++;
377 have_chunk = 1;
381 // Assume the chunk exists by now and rely on libogg to say if it's out of
382 // data.
383 have_chunk = 1;
395 // Read chunks until output buffer is on or after end_position
396 result = 0;
397 while(codec->output_position < end_position)
401 // Read chunk to decode if it hasn't been read yet.
402 if(!have_chunk)
404 codec->chunk_samples = 0;
406 READ_CHUNK(codec->chunk);
407 if(result) break;
408 codec->chunk++;
411 eos = 0;
412 while(!eos)
414 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
422 // Need more data from chunk
423 if(result == 0)
425 // End of chunk
426 eos = 1;
428 else
429 // This stage checks for OggS and a checksum error.
430 // It doesn't tell if it's the end of a chunk. Need to manually parse OggS
431 // pages to figure out how big the chunk is.
432 if(result < 0)
434 //printf("ogg_sync_pageout=-1\n");
437 else
439 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
443 while(!eos)
445 //printf("decode 7\n");
446 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
448 //printf("decode 8 %d\n", result);
449 if(result == 0)
451 //printf("ogg_stream_packetout=0\n");
452 // End of page
453 eos = 1;
455 else
456 // This stage doesn't check for OggS.
457 if(result < 0)
459 //printf("ogg_stream_packetout=-1\n");
461 else
463 float **pcm;
471 if(vorbis_synthesis(&codec->dec_vb, &codec->dec_op) == 0)
473 vorbis_synthesis_blockin(&codec->dec_vd,
474 &codec->dec_vb);
478 while((result = vorbis_synthesis_pcmout(&codec->dec_vd, &pcm)) > 0)
480 //printf("vorbis_synthesis_pcmout=%x\n", result);
481 for(i = 0; i < track_map->channels; i++)
483 float *output_channel = codec->output[i];
484 float *input_channel = pcm[i];
485 int k = codec->output_end;
487 for(j = 0; j < result; j++)
489 output_channel[k++] = input_channel[j];
490 if(k >= codec->output_allocated)
491 k = 0;
494 if(i == track_map->channels - 1)
495 codec->output_end = k;
497 //printf("codec->output_end = %d\n", codec->output_end);
499 codec->output_position += result;
500 codec->output_size += result;
501 codec->chunk_samples += result;
502 if(codec->output_size > codec->output_allocated)
503 codec->output_size = codec->output_allocated;
504 vorbis_synthesis_read(&codec->dec_vd, result);
507 //printf("decode 11\n");
510 // Reset end of page so it isn't interpreted as an end of chunk
511 eos = 0;
516 // Next chunk
517 if(eos)
519 //printf("decode 12 got=%x\n", codec->chunk_samples);
520 have_chunk = 0;
525 // Fill silence
526 while(codec->output_position < end_position)
528 for(i = 0; i < track_map->channels; i++)
529 codec->output[i][codec->output_end] = 0;
531 codec->output_end++;
532 if(codec->output_end >= codec->output_allocated)
533 codec->output_end = 0;
534 codec->output_position++;
536 //printf("decode 15\n");
539 //printf("decode 2 codec->output_position=%lld codec->output_end=%d codec->output_size=%d\n",
540 // codec->output_position, codec->output_end, codec->output_size);
542 current_position = track_map->current_position;
543 i = codec->output_end - (codec->output_position - current_position);
544 j = 0;
545 while(i < 0) i += codec->output_allocated;
546 pcm = codec->output[channel];
548 if(output_i)
550 for( ; j < samples; j++)
552 int sample = pcm[i] * 32767;
553 CLAMP(sample, -32768, 32767);
554 output_i[j] = sample;
556 i++;
557 if(i >= codec->output_allocated) i = 0;
560 else
561 if(output_f)
563 for( ; j < samples; j++)
565 output_f[j] = pcm[i];
566 i++;
567 if(i >= codec->output_allocated) i = 0;
570 //printf("decode 16\n");
572 return 0;
594 #define FLUSH_OGG1 \
595 while(1) \
597 int eos = !ogg_stream_flush(&codec->enc_os, &codec->enc_og); \
598 if(eos) break; \
600 if(!chunk_started) \
602 chunk_started = 1; \
603 quicktime_write_chunk_header(file, trak, &chunk_atom); \
606 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
607 size += codec->enc_og.header_len; \
609 if(!result) \
611 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
612 size += codec->enc_og.body_len; \
616 if(!result) break; \
621 #define FLUSH_OGG2 \
622 while(vorbis_analysis_blockout(&codec->enc_vd, &codec->enc_vb) == 1) \
624 vorbis_analysis(&codec->enc_vb, &codec->enc_op); \
625 vorbis_bitrate_addblock(&codec->enc_vb); \
626 while(vorbis_bitrate_flushpacket(&codec->enc_vd, &codec->enc_op)) \
628 ogg_stream_packetin(&codec->enc_os, &codec->enc_op); \
630 while(!result) \
632 if(!ogg_stream_pageout(&codec->enc_os, &codec->enc_og)) break; \
635 if(!chunk_started) \
637 chunk_started = 1; \
638 quicktime_write_chunk_header(file, trak, &chunk_atom); \
640 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
641 size += codec->enc_og.header_len; \
643 if(!result) \
645 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
646 size += codec->enc_og.body_len; \
649 if(ogg_page_eos(&codec->enc_og)) break; \
655 static int encode(quicktime_t *file,
656 int16_t **input_i,
657 float **input_f,
658 int track,
659 long samples)
661 int result = 0;
662 int64_t offset = quicktime_position(file);
663 quicktime_audio_map_t *track_map = &(file->atracks[track]);
664 quicktime_trak_t *trak = track_map->track;
665 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
666 int samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
667 float **output;
668 int size = 0;
669 int chunk_started = 0;
670 quicktime_atom_t chunk_atom;
678 if(!codec->encode_initialized)
680 ogg_packet header;
681 ogg_packet header_comm;
682 ogg_packet header_code;
685 codec->encode_initialized = 1;
686 if(file->use_avi)
687 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
688 vorbis_info_init(&codec->enc_vi);
690 if(codec->use_vbr)
692 result = vorbis_encode_setup_managed(&codec->enc_vi,
693 track_map->channels,
694 samplerate,
695 codec->max_bitrate,
696 codec->nominal_bitrate,
697 codec->min_bitrate);
698 result |= vorbis_encode_ctl(&codec->enc_vi, OV_ECTL_RATEMANAGE_AVG, NULL);
699 result |= vorbis_encode_setup_init(&codec->enc_vi);
701 else
703 vorbis_encode_init(&codec->enc_vi,
704 track_map->channels,
705 samplerate,
706 codec->max_bitrate,
707 codec->nominal_bitrate,
708 codec->min_bitrate);
712 vorbis_comment_init(&codec->enc_vc);
713 vorbis_analysis_init(&codec->enc_vd, &codec->enc_vi);
714 vorbis_block_init(&codec->enc_vd, &codec->enc_vb);
715 srand(time(NULL));
716 ogg_stream_init(&codec->enc_os, rand());
719 vorbis_analysis_headerout(&codec->enc_vd,
720 &codec->enc_vc,
721 &header,
722 &header_comm,
723 &header_code);
725 ogg_stream_packetin(&codec->enc_os, &header);
726 ogg_stream_packetin(&codec->enc_os, &header_comm);
727 ogg_stream_packetin(&codec->enc_os, &header_code);
729 FLUSH_OGG1
732 output = vorbis_analysis_buffer(&codec->enc_vd, samples);
734 if(input_i)
736 int i, j;
737 for(i = 0; i < track_map->channels; i++)
739 for(j = 0; j < samples; j++)
741 output[i][j] = (float)input_i[i][j] / (float)32768;
745 else
746 if(input_f)
748 int i;
749 for(i = 0; i < track_map->channels; i++)
751 memcpy(output[i], input_f[i], sizeof(float) * samples);
755 vorbis_analysis_wrote(&codec->enc_vd, samples);
757 FLUSH_OGG2
759 codec->next_chunk_size += samples;
761 // Wrote a chunk.
762 if(chunk_started)
764 int new_encoded_samples = codec->enc_vd.granulepos;
765 quicktime_write_chunk_footer(file,
766 trak,
767 track_map->current_chunk,
768 &chunk_atom,
769 new_encoded_samples - codec->encoded_samples);
770 track_map->current_chunk++;
771 codec->next_chunk_size = 0;
772 codec->encoded_samples = new_encoded_samples;
775 return result;
781 static int set_parameter(quicktime_t *file,
782 int track,
783 char *key,
784 void *value)
786 quicktime_audio_map_t *atrack = &(file->atracks[track]);
787 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
790 if(!strcasecmp(key, "vorbis_vbr"))
791 codec->use_vbr = *(int*)value;
792 else
793 if(!strcasecmp(key, "vorbis_bitrate"))
794 codec->nominal_bitrate = *(int*)value;
795 else
796 if(!strcasecmp(key, "vorbis_max_bitrate"))
797 codec->max_bitrate = *(int*)value;
798 else
799 if(!strcasecmp(key, "vorbis_min_bitrate"))
800 codec->min_bitrate = *(int*)value;
801 return 0;
805 static void flush(quicktime_t *file, int track)
807 int result = 0;
808 int size = 0;
809 int64_t offset = quicktime_position(file);
810 quicktime_audio_map_t *track_map = &(file->atracks[track]);
811 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
812 long output_position = codec->enc_vd.granulepos;
813 int chunk_started = 0;
814 quicktime_atom_t chunk_atom;
815 quicktime_trak_t *trak = track_map->track;
817 //printf("flush 1\n");
818 vorbis_analysis_wrote(&codec->enc_vd,0);
820 FLUSH_OGG2
822 //printf("flush 2 %d\n", size);
823 if(chunk_started)
825 int new_encoded_samples = codec->enc_vd.granulepos;
826 quicktime_write_chunk_footer(file,
827 trak,
828 track_map->current_chunk,
829 &chunk_atom,
830 new_encoded_samples - codec->encoded_samples);
831 track_map->current_chunk++;
832 codec->next_chunk_size = 0;
836 void quicktime_init_codec_vorbis(quicktime_audio_map_t *atrack)
838 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
839 quicktime_vorbis_codec_t *codec;
841 /* Init public items */
842 codec_base->priv = calloc(1, sizeof(quicktime_vorbis_codec_t));
843 codec_base->delete_acodec = delete_codec;
844 codec_base->decode_audio = decode;
845 codec_base->encode_audio = encode;
846 codec_base->set_parameter = set_parameter;
847 codec_base->flush = flush;
848 codec_base->fourcc = QUICKTIME_VORBIS;
849 codec_base->title = "OGG Vorbis";
850 codec_base->desc = "OGG Vorbis for video. (Not standardized)";
852 codec = codec_base->priv;
853 codec->nominal_bitrate = 128000;
854 codec->max_bitrate = -1;
855 codec->min_bitrate = -1;