r563: Ogg theora+vorbis export added
[cinelerra_cv/mob.git] / quicktime / vorbis.c
blob45279ce67072b314174ac07db9bba16a33fb1cbd
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;
26 // Number of bytes written to disk
27 int64_t encoded_bytes;
30 // Number of samples encoded into the chunk
31 int next_chunk_size;
35 ogg_sync_state dec_oy; /* sync and verify incoming physical bitstream */
36 ogg_stream_state dec_os; /* take physical pages, weld into a logical
37 stream of packets */
38 ogg_page dec_og; /* one Ogg bitstream page. Vorbis packets are inside */
39 ogg_packet dec_op; /* one raw packet of data for decode */
41 vorbis_info dec_vi; /* struct that stores all the static vorbis bitstream
42 settings */
43 vorbis_comment dec_vc; /* struct that stores all the bitstream user comments */
44 vorbis_dsp_state dec_vd; /* central working state for the packet->PCM decoder */
45 vorbis_block dec_vb; /* local working space for packet->PCM decode */
47 unsigned int dec_current_serialno;
48 int decode_initialized;
49 float **output;
51 // Number of last sample relative to file
52 int64_t output_position;
53 // Number of last sample relative to output buffer
54 long output_end;
55 // Number of samples in output buffer
56 long output_size;
57 // Number of samples allocated in output buffer
58 long output_allocated;
59 // Current reading position in file
60 int64_t chunk;
61 // Number of samples decoded in the current chunk
62 int chunk_samples;
63 } quicktime_vorbis_codec_t;
66 /* =================================== public for vorbis */
68 static int delete_codec(quicktime_audio_map_t *atrack)
70 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
71 int i;
73 if(codec->encode_initialized)
75 ogg_stream_clear(&codec->enc_os);
76 vorbis_block_clear(&codec->enc_vb);
77 vorbis_dsp_clear(&codec->enc_vd);
78 vorbis_comment_clear(&codec->enc_vc);
79 vorbis_info_clear(&codec->enc_vi);
82 if(codec->decode_initialized)
84 if(codec->output)
86 for(i = 0; i < atrack->channels; i++)
87 free(codec->output[i]);
89 free(codec->output);
92 ogg_stream_clear(&codec->dec_os);
93 vorbis_block_clear(&codec->dec_vb);
94 vorbis_dsp_clear(&codec->dec_vd);
95 vorbis_comment_clear(&codec->dec_vc);
96 vorbis_info_clear(&codec->dec_vi);
99 free(codec);
100 return 0;
107 // Buffer fragment should be bigger then largest page header so
108 // all lacing bytes can be decoded.
109 #define BUFFER_FRAGMENT 4096
111 // Calculate chunk length from OggS headers. This is the worst case
112 // but it's better not to assume libogg is going to do anything for us.
114 #define SEGMENT_OFFSET 0x1a
115 #define LACE_OFFSET 0x1b
116 static int chunk_len(quicktime_t *file, int64_t offset, int64_t next_chunk)
118 int result = 0;
119 unsigned char buffer[BUFFER_FRAGMENT];
120 int accum = 0;
121 int segment_count = 0;
122 int segment_size = 0;
123 int lace_size = 0;
124 int page_size = 0;
125 int i, j;
127 while(offset < next_chunk)
129 quicktime_set_position(file, offset);
130 result = !quicktime_read_data(file, buffer, BUFFER_FRAGMENT);
132 if(result)
134 return accum;
137 if(memcmp(buffer, "OggS", 4))
139 return accum;
141 else
145 // Decode size of OggS page
146 segment_count = buffer[SEGMENT_OFFSET];
148 // Decode one segment at a time
149 i = LACE_OFFSET;
150 page_size = 0;
151 while(segment_count > 0)
153 page_size += buffer[i++];
154 segment_count--;
156 accum += i + page_size;
157 offset += i + page_size;
161 return accum;
165 // Calculates the chunk size based on ogg pages.
166 #define READ_CHUNK(chunk) \
168 int64_t offset1 = quicktime_chunk_to_offset(file, trak, (chunk)); \
169 int64_t offset2 = quicktime_chunk_to_offset(file, trak, (chunk) + 1); \
170 int size = 0; \
171 if(offset2 == offset1) \
172 result = 1; \
173 else \
175 size = chunk_len(file, offset1, \
176 offset2 > offset1 ? offset2 : offset1 + 0xfffff); \
178 buffer = ogg_sync_buffer(&codec->dec_oy, size); \
179 quicktime_set_position(file, offset1); \
180 result = !quicktime_read_data(file, buffer, size); \
181 ogg_sync_wrote(&codec->dec_oy, size); \
183 /* printf("READ_CHUNK size=%d\n", size); */ \
184 /* printf("%llx %x: ", quicktime_chunk_to_offset(file, trak, (chunk)), size); */ \
185 /* for(i = 0; i < 16; i++) */ \
186 /* printf("%02x ", buffer[i]); */ \
187 /* printf("result=%d\n", result); */ \
193 static int decode(quicktime_t *file,
194 int16_t *output_i,
195 float *output_f,
196 long samples,
197 int track,
198 int channel)
200 int result = 0;
201 int bytes;
202 int i, j;
203 quicktime_audio_map_t *track_map = &(file->atracks[track]);
204 quicktime_trak_t *trak = track_map->track;
205 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
206 long current_position = track_map->current_position;
207 long end_position = current_position + samples;
208 unsigned char *buffer;
209 // End of data in ogg buffer
210 int eos = 0;
211 // End of file
212 int eof = 0;
213 float *pcm;
214 int have_chunk = 0;
217 if(samples > OUTPUT_ALLOCATION)
218 printf("vorbis.c decode: can't read more than %p samples at a time.\n", OUTPUT_ALLOCATION);
222 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
223 if(output_f) bzero(output_f, sizeof(float) * samples);
231 // Seeked outside output buffer's range or not initialized: restart
232 if(current_position < codec->output_position - codec->output_size ||
233 current_position > codec->output_position ||
234 !codec->decode_initialized)
237 quicktime_chunk_of_sample(&codec->output_position,
238 &codec->chunk,
239 trak,
240 current_position);
241 // We know the first ogg packet in the chunk has a pcm_offset from the encoding.
243 codec->output_size = 0;
244 codec->output_end = 0;
245 codec->chunk_samples = 0;
250 // Initialize and load initial buffer for decoding
251 if(!codec->decode_initialized)
253 int init_chunk = 1;
254 codec->decode_initialized = 1;
256 codec->output = malloc(sizeof(float*) * track_map->channels);
257 for(i = 0; i < track_map->channels; i++)
259 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
262 codec->output_allocated = OUTPUT_ALLOCATION;
264 ogg_sync_init(&codec->dec_oy); /* Now we can read pages */
269 READ_CHUNK(init_chunk);
270 init_chunk++;
272 if(ogg_sync_pageout(&codec->dec_oy, &codec->dec_og)!=1)
274 fprintf(stderr, "decode: ogg_sync_pageout: Must not be Vorbis data\n");
275 return 1;
279 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
280 vorbis_info_init(&codec->dec_vi);
281 vorbis_comment_init(&codec->dec_vc);
283 if(ogg_stream_pagein(&codec->dec_os, &codec->dec_og) < 0)
285 fprintf(stderr,"decode: ogg_stream_pagein: stream version mismatch perhaps.\n");
286 return 1;
289 if(ogg_stream_packetout(&codec->dec_os, &codec->dec_op) != 1)
291 fprintf(stderr, "decode: ogg_stream_packetout: Must not be Vorbis data\n");
292 return 1;
295 if(vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op) < 0)
297 fprintf(stderr, "decode: vorbis_synthesis_headerin: not a vorbis header\n");
298 return 1;
302 i = 0;
303 while(i < 2)
305 while(i < 2)
307 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
308 if(result == 0) break;
310 if(result == 1)
312 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
314 while(i < 2)
316 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
318 if(result == 0) break;
320 if(result < 0)
322 fprintf(stderr, "decode: ogg_stream_packetout: corrupt secondary header\n");
323 return 1;
326 vorbis_synthesis_headerin(&codec->dec_vi, &codec->dec_vc, &codec->dec_op);
327 i++;
336 if(i < 2)
338 READ_CHUNK(init_chunk);
339 init_chunk++;
342 // Header should never span more than one chunk so assume it's done here
345 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
346 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
348 // Also the first chunk needed in decoding so don't reread after this.
349 if(codec->chunk == init_chunk - 1)
351 have_chunk = 1;
352 codec->chunk++;
359 // Don't already have initial chunk from header
360 if(!have_chunk)
362 // Get initial chunk for decoding at new location
363 // From vorbisfile.c
364 /* clear out decoding machine state */
365 ogg_stream_clear(&codec->dec_os);
366 vorbis_dsp_clear(&codec->dec_vd);
367 vorbis_block_clear(&codec->dec_vb);
368 ogg_sync_reset(&codec->dec_oy);
370 ogg_stream_init(&codec->dec_os, ogg_page_serialno(&codec->dec_og));
371 ogg_sync_init(&codec->dec_oy);
372 vorbis_synthesis_init(&codec->dec_vd, &codec->dec_vi);
373 vorbis_block_init(&codec->dec_vd, &codec->dec_vb);
376 READ_CHUNK(codec->chunk);
377 codec->chunk++;
378 have_chunk = 1;
382 // Assume the chunk exists by now and rely on libogg to say if it's out of
383 // data.
384 have_chunk = 1;
396 // Read chunks until output buffer is on or after end_position
397 result = 0;
398 while(codec->output_position < end_position)
402 // Read chunk to decode if it hasn't been read yet.
403 if(!have_chunk)
405 codec->chunk_samples = 0;
407 READ_CHUNK(codec->chunk);
408 if(result) break;
409 codec->chunk++;
412 eos = 0;
413 while(!eos)
415 result = ogg_sync_pageout(&codec->dec_oy, &codec->dec_og);
423 // Need more data from chunk
424 if(result == 0)
426 // End of chunk
427 eos = 1;
429 else
430 // This stage checks for OggS and a checksum error.
431 // It doesn't tell if it's the end of a chunk. Need to manually parse OggS
432 // pages to figure out how big the chunk is.
433 if(result < 0)
435 //printf("ogg_sync_pageout=-1\n");
438 else
440 ogg_stream_pagein(&codec->dec_os, &codec->dec_og);
444 while(!eos)
446 //printf("decode 7\n");
447 result = ogg_stream_packetout(&codec->dec_os, &codec->dec_op);
449 //printf("decode 8 %d\n", result);
450 if(result == 0)
452 //printf("ogg_stream_packetout=0\n");
453 // End of page
454 eos = 1;
456 else
457 // This stage doesn't check for OggS.
458 if(result < 0)
460 //printf("ogg_stream_packetout=-1\n");
462 else
464 float **pcm;
472 if(vorbis_synthesis(&codec->dec_vb, &codec->dec_op) == 0)
474 vorbis_synthesis_blockin(&codec->dec_vd,
475 &codec->dec_vb);
479 while((result = vorbis_synthesis_pcmout(&codec->dec_vd, &pcm)) > 0)
481 //printf("vorbis_synthesis_pcmout=%x\n", result);
482 for(i = 0; i < track_map->channels; i++)
484 float *output_channel = codec->output[i];
485 float *input_channel = pcm[i];
486 int k = codec->output_end;
488 for(j = 0; j < result; j++)
490 output_channel[k++] = input_channel[j];
491 if(k >= codec->output_allocated)
492 k = 0;
495 if(i == track_map->channels - 1)
496 codec->output_end = k;
498 //printf("codec->output_end = %d\n", codec->output_end);
500 codec->output_position += result;
501 codec->output_size += result;
502 codec->chunk_samples += result;
503 if(codec->output_size > codec->output_allocated)
504 codec->output_size = codec->output_allocated;
505 vorbis_synthesis_read(&codec->dec_vd, result);
508 //printf("decode 11\n");
511 // Reset end of page so it isn't interpreted as an end of chunk
512 eos = 0;
517 // Next chunk
518 if(eos)
520 //printf("decode 12 got=%x\n", codec->chunk_samples);
521 have_chunk = 0;
526 // Fill silence
527 while(codec->output_position < end_position)
529 for(i = 0; i < track_map->channels; i++)
530 codec->output[i][codec->output_end] = 0;
532 codec->output_end++;
533 if(codec->output_end >= codec->output_allocated)
534 codec->output_end = 0;
535 codec->output_position++;
537 //printf("decode 15\n");
540 //printf("decode 2 codec->output_position=%lld codec->output_end=%d codec->output_size=%d\n",
541 // codec->output_position, codec->output_end, codec->output_size);
543 current_position = track_map->current_position;
544 i = codec->output_end - (codec->output_position - current_position);
545 j = 0;
546 while(i < 0) i += codec->output_allocated;
547 pcm = codec->output[channel];
549 if(output_i)
551 for( ; j < samples; j++)
553 int sample = pcm[i] * 32767;
554 CLAMP(sample, -32768, 32767);
555 output_i[j] = sample;
557 i++;
558 if(i >= codec->output_allocated) i = 0;
561 else
562 if(output_f)
564 for( ; j < samples; j++)
566 output_f[j] = pcm[i];
567 i++;
568 if(i >= codec->output_allocated) i = 0;
571 //printf("decode 16\n");
573 return 0;
595 #define FLUSH_OGG1 \
596 while(1) \
598 int eos = !ogg_stream_flush(&codec->enc_os, &codec->enc_og); \
599 if(eos) break; \
601 if(!chunk_started) \
603 chunk_started = 1; \
604 quicktime_write_chunk_header(file, trak, &chunk_atom); \
607 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
608 size += codec->enc_og.header_len; \
610 if(!result) \
612 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
613 size += codec->enc_og.body_len; \
617 if(!result) break; \
622 #define FLUSH_OGG2 \
623 while(vorbis_analysis_blockout(&codec->enc_vd, &codec->enc_vb) == 1) \
625 vorbis_analysis(&codec->enc_vb, &codec->enc_op); \
626 vorbis_bitrate_addblock(&codec->enc_vb); \
627 while(vorbis_bitrate_flushpacket(&codec->enc_vd, &codec->enc_op)) \
629 ogg_stream_packetin(&codec->enc_os, &codec->enc_op); \
631 while(!result) \
633 if(!ogg_stream_pageout(&codec->enc_os, &codec->enc_og)) break; \
636 if(!chunk_started) \
638 chunk_started = 1; \
639 quicktime_write_chunk_header(file, trak, &chunk_atom); \
641 result = !quicktime_write_data(file, codec->enc_og.header, codec->enc_og.header_len); \
642 size += codec->enc_og.header_len; \
644 if(!result) \
646 result = !quicktime_write_data(file, codec->enc_og.body, codec->enc_og.body_len); \
647 size += codec->enc_og.body_len; \
650 if(ogg_page_eos(&codec->enc_og)) break; \
656 static int encode(quicktime_t *file,
657 int16_t **input_i,
658 float **input_f,
659 int track,
660 long samples)
662 int result = 0;
663 int64_t offset = quicktime_position(file);
664 quicktime_audio_map_t *track_map = &(file->atracks[track]);
665 quicktime_trak_t *trak = track_map->track;
666 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
667 int samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
668 float **output;
669 int size = 0;
670 int chunk_started = 0;
671 quicktime_atom_t chunk_atom;
674 if(samplerate < 32000)
676 printf("encode: sample rate %d not supported.\n", samplerate);
677 return 1;
684 if(!codec->encode_initialized)
686 ogg_packet header;
687 ogg_packet header_comm;
688 ogg_packet header_code;
691 codec->encode_initialized = 1;
692 if(file->use_avi)
693 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
694 vorbis_info_init(&codec->enc_vi);
696 if(codec->use_vbr)
698 result = vorbis_encode_setup_managed(&codec->enc_vi,
699 track_map->channels,
700 samplerate,
701 codec->max_bitrate,
702 codec->nominal_bitrate,
703 codec->min_bitrate);
704 result |= vorbis_encode_ctl(&codec->enc_vi, OV_ECTL_RATEMANAGE_AVG, NULL);
705 result |= vorbis_encode_setup_init(&codec->enc_vi);
707 else
709 vorbis_encode_init(&codec->enc_vi,
710 track_map->channels,
711 samplerate,
712 codec->max_bitrate,
713 codec->nominal_bitrate,
714 codec->min_bitrate);
718 vorbis_comment_init(&codec->enc_vc);
719 vorbis_analysis_init(&codec->enc_vd, &codec->enc_vi);
720 vorbis_block_init(&codec->enc_vd, &codec->enc_vb);
721 srand(time(NULL));
722 ogg_stream_init(&codec->enc_os, rand());
725 vorbis_analysis_headerout(&codec->enc_vd,
726 &codec->enc_vc,
727 &header,
728 &header_comm,
729 &header_code);
731 ogg_stream_packetin(&codec->enc_os, &header);
732 ogg_stream_packetin(&codec->enc_os, &header_comm);
733 ogg_stream_packetin(&codec->enc_os, &header_code);
735 FLUSH_OGG1
738 output = vorbis_analysis_buffer(&codec->enc_vd, samples);
740 if(input_i)
742 int i, j;
743 for(i = 0; i < track_map->channels; i++)
745 for(j = 0; j < samples; j++)
747 output[i][j] = (float)input_i[i][j] / (float)32768;
751 else
752 if(input_f)
754 int i;
755 for(i = 0; i < track_map->channels; i++)
757 memcpy(output[i], input_f[i], sizeof(float) * samples);
761 vorbis_analysis_wrote(&codec->enc_vd, samples);
763 FLUSH_OGG2
765 codec->next_chunk_size += samples;
767 // Wrote a chunk.
768 if(chunk_started)
770 int new_encoded_samples = codec->enc_vd.granulepos;
771 // granulepos is meaningless for fixed bitrate
772 if(!codec->use_vbr)
774 codec->encoded_bytes += quicktime_position(file) - offset;
775 new_encoded_samples = codec->encoded_bytes *
776 (int64_t)8 *
777 (int64_t)samplerate /
778 (int64_t)codec->nominal_bitrate;
780 quicktime_write_chunk_footer(file,
781 trak,
782 track_map->current_chunk,
783 &chunk_atom,
784 new_encoded_samples - codec->encoded_samples);
785 track_map->current_chunk++;
786 codec->next_chunk_size = 0;
787 codec->encoded_samples = new_encoded_samples;
790 return result;
796 static int set_parameter(quicktime_t *file,
797 int track,
798 char *key,
799 void *value)
801 quicktime_audio_map_t *atrack = &(file->atracks[track]);
802 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
805 if(!strcasecmp(key, "vorbis_vbr"))
806 codec->use_vbr = *(int*)value;
807 else
808 if(!strcasecmp(key, "vorbis_bitrate"))
809 codec->nominal_bitrate = *(int*)value;
810 else
811 if(!strcasecmp(key, "vorbis_max_bitrate"))
812 codec->max_bitrate = *(int*)value;
813 else
814 if(!strcasecmp(key, "vorbis_min_bitrate"))
815 codec->min_bitrate = *(int*)value;
816 return 0;
820 static void flush(quicktime_t *file, int track)
822 quicktime_audio_map_t *track_map = &(file->atracks[track]);
823 quicktime_vorbis_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
824 if(codec->encode_initialized)
826 int result = 0;
827 int size = 0;
828 int64_t offset = quicktime_position(file);
829 long output_position = codec->enc_vd.granulepos;
830 int chunk_started = 0;
831 quicktime_trak_t *trak = track_map->track;
832 int sample_rate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
833 quicktime_atom_t chunk_atom;
835 vorbis_analysis_wrote(&codec->enc_vd,0);
837 FLUSH_OGG2
839 if(chunk_started)
841 int new_encoded_samples = codec->enc_vd.granulepos;
842 if(!codec->use_vbr)
844 codec->encoded_bytes += quicktime_position(file) - offset;
845 new_encoded_samples = codec->encoded_bytes *
846 (int64_t)8 *
847 (int64_t)sample_rate /
848 (int64_t)codec->nominal_bitrate;
850 quicktime_write_chunk_footer(file,
851 trak,
852 track_map->current_chunk,
853 &chunk_atom,
854 new_encoded_samples - codec->encoded_samples);
855 track_map->current_chunk++;
856 codec->next_chunk_size = 0;
861 void quicktime_init_codec_vorbis(quicktime_audio_map_t *atrack)
863 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
864 quicktime_vorbis_codec_t *codec;
866 /* Init public items */
867 codec_base->priv = calloc(1, sizeof(quicktime_vorbis_codec_t));
868 codec_base->delete_acodec = delete_codec;
869 codec_base->decode_audio = decode;
870 codec_base->encode_audio = encode;
871 codec_base->set_parameter = set_parameter;
872 codec_base->flush = flush;
873 codec_base->fourcc = QUICKTIME_VORBIS;
874 codec_base->title = "OGG Vorbis";
875 codec_base->desc = "OGG Vorbis for video. (Not standardized)";
877 codec = codec_base->priv;
878 codec->nominal_bitrate = 128000;
879 codec->max_bitrate = -1;
880 codec->min_bitrate = -1;