3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
6 ** Copyright 2000-2002, Michael Smith <msmith@xiph.org>
8 ** Portions from Vorbize, (c) Kenneth Arnold <kcarnold-xiph@arnoldnet.net>
9 ** and libvorbis examples, (c) Monty <monty@xiph.org>
23 #include <vorbis/vorbisenc.h>
30 #include <kate/oggkate.h>
36 int oe_write_page(ogg_page
*page
, FILE *fp
);
40 if(sscanf(opts[i].val, "%lf", &dval) != 1)\
41 fprintf(stderr, "For option %s, couldn't read value %s as double\n",\
42 opts[i].arg, opts[i].val);\
49 if(sscanf(opts[i].val, "%ld", &lval) != 1)\
50 fprintf(stderr, "For option %s, couldn't read value %s as integer\n",\
51 opts[i].arg, opts[i].val);\
56 static void set_advanced_encoder_options(adv_opt
*opts
, int count
,
59 #ifdef OV_ECTL_RATEMANAGE2_GET
61 struct ovectl_ratemanage2_arg ai
;
66 vorbis_encode_ctl(vi
, OV_ECTL_RATEMANAGE2_GET
, &ai
);
68 for(i
=0; i
< count
; i
++) {
70 fprintf(stderr
, _("Setting advanced encoder option \"%s\" to %s\n"),
71 opts
[i
].arg
, opts
[i
].val
);
73 fprintf(stderr
, _("Setting advanced encoder option \"%s\"\n"),
76 if(!strcmp(opts
[i
].arg
, "bitrate_average_damping")) {
77 SETD(ai
.bitrate_average_damping
);
80 else if(!strcmp(opts
[i
].arg
, "bitrate_average")) {
81 SETL(ai
.bitrate_average_kbps
);
84 else if(!strcmp(opts
[i
].arg
, "bit_reservoir_bias")) {
85 SETD(ai
.bitrate_limit_reservoir_bias
);
88 else if(!strcmp(opts
[i
].arg
, "bit_reservoir_bits")) {
89 SETL(ai
.bitrate_limit_reservoir_bits
);
92 else if(!strcmp(opts
[i
].arg
, "bitrate_hard_min")) {
93 SETL(ai
.bitrate_limit_min_kbps
);
96 else if(!strcmp(opts
[i
].arg
, "bitrate_hard_max")) {
97 SETL(ai
.bitrate_limit_max_kbps
);
100 else if(!strcmp(opts
[i
].arg
, "disable_coupling")) {
102 vorbis_encode_ctl(vi
, OV_ECTL_COUPLING_SET
, &val
);
104 else if(!strcmp(opts
[i
].arg
, "impulse_noisetune")) {
107 vorbis_encode_ctl(vi
, OV_ECTL_IBLOCK_SET
, &val
);
109 else if(!strcmp(opts
[i
].arg
, "lowpass_frequency")) {
112 vorbis_encode_ctl(vi
, OV_ECTL_LOWPASS_GET
, &prev
);
113 vorbis_encode_ctl(vi
, OV_ECTL_LOWPASS_SET
, &new);
114 fprintf(stderr
, _("Changed lowpass frequency from %f kHz to %f kHz\n"), prev
, new);
117 fprintf(stderr
, _("Unrecognised advanced option \"%s\"\n"),
123 if(vorbis_encode_ctl(vi
, OV_ECTL_RATEMANAGE2_SET
, &ai
)) {
124 fprintf(stderr
, _("Failed to set advanced rate management parameters\n"));
128 fprintf(stderr
,_( "This version of libvorbisenc cannot set advanced rate management parameters\n"));
132 static void add_fishead_packet (ogg_stream_state
*os
) {
136 memset(&fp
, 0, sizeof(fp
));
142 add_fishead_to_stream(os
, &fp
);
146 * Adds the fishead packets in the skeleton output stream
148 static void add_vorbis_fisbone_packet (ogg_stream_state
*os
, oe_enc_opt
*opt
) {
152 memset(&fp
, 0, sizeof(fp
));
153 fp
.serial_no
= opt
->serialno
;
154 fp
.nr_header_packet
= 3;
155 fp
.granule_rate_n
= opt
->rate
;
156 fp
.granule_rate_d
= 1;
157 fp
.start_granule
= 0;
159 fp
.granule_shift
= 0;
161 add_message_header_field(&fp
, "Content-Type", "audio/vorbis");
163 add_fisbone_to_stream(os
, &fp
);
167 static void add_kate_fisbone_packet (ogg_stream_state
*os
, oe_enc_opt
*opt
, kate_info
*ki
) {
171 memset(&fp
, 0, sizeof(fp
));
172 fp
.serial_no
= opt
->kate_serialno
;
173 fp
.nr_header_packet
= ki
->num_headers
;
174 fp
.granule_rate_n
= ki
->gps_numerator
;
175 fp
.granule_rate_d
= ki
->gps_denominator
;
176 fp
.start_granule
= 0;
178 fp
.granule_shift
= ki
->granule_shift
;
180 add_message_header_field(&fp
, "Content-Type", "application/x-kate");
182 add_fisbone_to_stream(os
, &fp
);
187 static void add_kate_karaoke_style(kate_info
*ki
,unsigned char r
,unsigned char g
,unsigned char b
,unsigned char a
)
194 ks
=(kate_style
*)malloc(sizeof(kate_style
));
196 ks
->text_color
.r
= r
;
197 ks
->text_color
.g
= g
;
198 ks
->text_color
.b
= b
;
199 ks
->text_color
.a
= a
;
200 ret
=kate_info_add_style(ki
,ks
);
202 fprintf(stderr
, _("WARNING: failed to add Kate karaoke style\n"));
207 int oe_encode(oe_enc_opt
*opt
)
211 ogg_stream_state so
; /* stream for skeleton bitstream */
212 ogg_stream_state ko
; /* stream for kate bitstream */
224 oe_lyrics
*lyrics
=NULL
;
225 size_t lyrics_index
=0;
226 double vorbis_time
= 0.0;
231 long bytes_written
= 0, packetsdone
=0;
237 if(opt
->channels
> 255) {
238 fprintf(stderr
, _("255 channels should be enough for anyone. (Sorry, but Vorbis doesn't support more)\n"));
242 /* get start time. */
243 timer
= timer_start();
245 if(!opt
->managed
&& (opt
->min_bitrate
>=0 || opt
->max_bitrate
>=0)){
246 fprintf(stderr
, _("Requesting a minimum or maximum bitrate requires --managed\n"));
250 /* if we had no quality or bitrate spec at all from the user, use
251 the default quality with no management --Monty 20020711 */
252 if(opt
->bitrate
< 0 && opt
->min_bitrate
< 0 && opt
->max_bitrate
< 0){
256 opt
->start_encode(opt
->infilename
, opt
->filename
, opt
->bitrate
, opt
->quality
,
257 opt
->quality_set
, opt
->managed
, opt
->min_bitrate
, opt
->max_bitrate
);
259 /* Have vorbisenc choose a mode for us */
260 vorbis_info_init(&vi
);
262 if(opt
->quality_set
> 0){
263 if(vorbis_encode_setup_vbr(&vi
, opt
->channels
, opt
->rate
, opt
->quality
)){
264 fprintf(stderr
, _("Mode initialisation failed: invalid parameters for quality\n"));
265 vorbis_info_clear(&vi
);
269 /* do we have optional hard bitrate restrictions? */
270 if(opt
->max_bitrate
> 0 || opt
->min_bitrate
> 0){
271 #ifdef OV_ECTL_RATEMANAGE2_GET
273 struct ovectl_ratemanage2_arg ai
;
275 vorbis_encode_ctl(&vi
, OV_ECTL_RATEMANAGE2_GET
, &ai
);
277 /* libvorbis 1.1 (and current svn) doesn't actually fill this in,
278 which looks like a bug. It'll then reject it when we call the
279 SET version below. So, fill it in with the values that libvorbis
280 would have used to fill in this structure if we were using the
281 bitrate-oriented setup functions. Unfortunately, some of those
282 values are dependent on the bitrate, and libvorbis has no way to
283 get a nominal bitrate from a quality value. Well, except by doing
284 a full setup... So, we do that.
285 Also, note that this won't work correctly unless you have
286 version 1.1.1 or later of libvorbis.
291 vorbis_info_init(&vi2
);
292 vorbis_encode_setup_vbr(&vi2
, opt
->channels
, opt
->rate
, opt
->quality
);
293 vorbis_encode_setup_init(&vi2
);
294 bitrate
= vi2
.bitrate_nominal
;
295 vorbis_info_clear(&vi2
);
298 ai
.bitrate_average_kbps
= bitrate
/1000;
299 ai
.bitrate_average_damping
= 1.5;
300 ai
.bitrate_limit_reservoir_bits
= bitrate
* 2;
301 ai
.bitrate_limit_reservoir_bias
= .1;
303 /* And now the ones we actually wanted to set */
304 ai
.bitrate_limit_min_kbps
=opt
->min_bitrate
;
305 ai
.bitrate_limit_max_kbps
=opt
->max_bitrate
;
306 ai
.management_active
=1;
308 if(vorbis_encode_ctl(&vi
, OV_ECTL_RATEMANAGE2_SET
, &ai
) == 0)
309 fprintf(stderr
, _("Set optional hard quality restrictions\n"));
311 fprintf(stderr
, _("Failed to set bitrate min/max in quality mode\n"));
312 vorbis_info_clear(&vi
);
316 fprintf(stderr
, _("This version of libvorbisenc cannot set advanced rate management parameters\n"));
323 if(vorbis_encode_setup_managed(&vi
, opt
->channels
, opt
->rate
,
324 opt
->max_bitrate
>0?opt
->max_bitrate
*1000:-1,
326 opt
->min_bitrate
>0?opt
->min_bitrate
*1000:-1)){
327 fprintf(stderr
, _("Mode initialisation failed: invalid parameters for bitrate\n"));
328 vorbis_info_clear(&vi
);
333 #ifdef OV_ECTL_RATEMANAGE2_SET
334 if(opt
->managed
&& opt
->bitrate
< 0)
336 struct ovectl_ratemanage2_arg ai
;
337 vorbis_encode_ctl(&vi
, OV_ECTL_RATEMANAGE2_GET
, &ai
);
338 ai
.bitrate_average_kbps
=-1;
339 vorbis_encode_ctl(&vi
, OV_ECTL_RATEMANAGE2_SET
, &ai
);
341 else if(!opt
->managed
)
343 /* Turn off management entirely (if it was turned on). */
344 vorbis_encode_ctl(&vi
, OV_ECTL_RATEMANAGE2_SET
, NULL
);
348 set_advanced_encoder_options(opt
->advopt
, opt
->advopt_count
, &vi
);
350 vorbis_encode_setup_init(&vi
);
353 /* Now, set up the analysis engine, stream encoder, and other
354 preparation before the encoding begins.
357 vorbis_analysis_init(&vd
,&vi
);
358 vorbis_block_init(&vd
,&vb
);
363 lyrics
=load_lyrics(opt
->lyrics
);
364 /* if it fails, don't do anything else for lyrics */
368 /* init kate for encoding */
370 kate_info_set_category(&ki
, "LRC");
371 if (opt
->lyrics_language
)
372 kate_info_set_language(&ki
, opt
->lyrics_language
);
374 fprintf(stderr
, _("WARNING: no language specified for %s\n"), opt
->lyrics
);
375 kate_comment_init(&kc
);
376 kate_encode_init(&k
,&ki
);
378 /* if we're in karaoke mode (we have syllable level timing info),
379 add style info in case some graphical player is used */
380 add_kate_karaoke_style(&ki
, 255, 255, 255, 255);
381 add_kate_karaoke_style(&ki
, 255, 128, 128, 255);
386 ogg_stream_init(&os
, opt
->serialno
);
387 if (opt
->with_skeleton
)
388 ogg_stream_init(&so
, opt
->skeleton_serialno
);
390 ogg_stream_init(&ko
, opt
->kate_serialno
);
392 /* create the skeleton fishead packet and output it */
393 if (opt
->with_skeleton
) {
394 add_fishead_packet(&so
);
395 if ((ret
= flush_ogg_stream_to_file(&so
, opt
->out
))) {
396 opt
->error(_("Failed writing fishead packet to output stream\n"));
401 /* Now, build the three header packets and send through to the stream
402 output stage (but defer actual file output until the main encode loop) */
405 ogg_packet header_main
;
406 ogg_packet header_comments
;
407 ogg_packet header_codebooks
;
409 /* Build the packets */
410 vorbis_analysis_headerout(&vd
,opt
->comments
,
411 &header_main
,&header_comments
,&header_codebooks
);
413 /* And stream them out */
414 /* output the vorbis bos first, then the kate bos, then the fisbone packets */
415 ogg_stream_packetin(&os
,&header_main
);
416 while((result
= ogg_stream_flush(&os
, &og
)))
419 ret
= oe_write_page(&og
, opt
->out
);
420 if(ret
!= og
.header_len
+ og
.body_len
)
422 opt
->error(_("Failed writing header to output stream\n"));
424 goto cleanup
; /* Bail and try to clean up stuff */
431 ret
= kate_ogg_encode_headers(&k
, &kc
, &kate_op
);
433 opt
->error(_("Failed encoding Kate header\n"));
436 ogg_stream_packetin(&ko
,&kate_op
);
437 while((result
= ogg_stream_flush(&ko
, &og
)))
440 ret
= oe_write_page(&og
, opt
->out
);
441 if(ret
!= og
.header_len
+ og
.body_len
)
443 opt
->error(_("Failed writing header to output stream\n"));
445 goto cleanup
; /* Bail and try to clean up stuff */
448 ogg_packet_clear(&kate_op
);
452 if (opt
->with_skeleton
) {
453 add_vorbis_fisbone_packet(&so
, opt
);
454 if ((ret
= flush_ogg_stream_to_file(&so
, opt
->out
))) {
455 opt
->error(_("Failed writing fisbone header packet to output stream\n"));
460 add_kate_fisbone_packet(&so
, opt
, &ki
);
461 if ((ret
= flush_ogg_stream_to_file(&so
, opt
->out
))) {
462 opt
->error(_("Failed writing fisbone header packet to output stream\n"));
469 /* write the next Vorbis headers */
470 ogg_stream_packetin(&os
,&header_comments
);
471 ogg_stream_packetin(&os
,&header_codebooks
);
473 while((result
= ogg_stream_flush(&os
, &og
)))
476 ret
= oe_write_page(&og
, opt
->out
);
477 if(ret
!= og
.header_len
+ og
.body_len
)
479 opt
->error(_("Failed writing header to output stream\n"));
481 goto cleanup
; /* Bail and try to clean up stuff */
486 /* build kate headers if requested */
489 while (kate_ogg_encode_headers(&k
,&kc
,&op
)==0) {
490 ogg_stream_packetin(&ko
,&op
);
491 ogg_packet_clear(&op
);
493 while((result
= ogg_stream_flush(&ko
, &og
)))
496 ret
= oe_write_page(&og
, opt
->out
);
497 if(ret
!= og
.header_len
+ og
.body_len
)
499 opt
->error(_("Failed writing header to output stream\n"));
501 goto cleanup
; /* Bail and try to clean up stuff */
507 if (opt
->with_skeleton
) {
508 add_eos_packet_to_stream(&so
);
509 if ((ret
= flush_ogg_stream_to_file(&so
, opt
->out
))) {
510 opt
->error(_("Failed writing skeleton eos packet to output stream\n"));
517 /* Main encode loop - continue until end of file */
520 float **buffer
= vorbis_analysis_buffer(&vd
, READSIZE
);
521 long samples_read
= opt
->read_samples(opt
->readdata
,
525 /* Tell the library that we wrote 0 bytes - signalling the end */
526 vorbis_analysis_wrote(&vd
,0);
529 samplesdone
+= samples_read
;
531 /* Call progress update every 40 pages */
537 time
= timer_time(timer
);
539 opt
->progress_update(opt
->filename
, opt
->total_samples_per_channel
,
543 /* Tell the library how many samples (per channel) we wrote
544 into the supplied buffer */
545 vorbis_analysis_wrote(&vd
, samples_read
);
548 /* While we can get enough data from the library to analyse, one
549 block at a time... */
550 while(vorbis_analysis_blockout(&vd
,&vb
)==1)
553 /* Do the main analysis, creating a packet */
554 vorbis_analysis(&vb
, NULL
);
555 vorbis_bitrate_addblock(&vb
);
557 while(vorbis_bitrate_flushpacket(&vd
, &op
))
559 /* Add packet to bitstream */
560 ogg_stream_packetin(&os
,&op
);
563 /* If we've gone over a page boundary, we can do actual output,
564 so do so (for however many pages are available) */
568 int result
= ogg_stream_pageout(&os
,&og
);
571 /* now that we have a new Vorbis page, we scan lyrics for any that is due */
573 if (opt
->lyrics
&& ogg_page_granulepos(&og
)>=0) {
574 vorbis_time
= vorbis_granule_time(&vd
, ogg_page_granulepos(&og
));
575 const oe_lyrics_item
*item
;
576 while ((item
= get_lyrics(lyrics
, vorbis_time
, &lyrics_index
))) {
579 ret
= kate_encode_set_style_index(&k
, 0);
581 opt
->error(_("Failed encoding karaoke style - continuing anyway\n"));
583 ret
= kate_encode_set_secondary_style_index(&k
, 1);
585 opt
->error(_("Failed encoding karaoke style - continuing anyway\n"));
587 ret
= kate_encode_add_motion(&k
, item
->km
, 0);
589 opt
->error(_("Failed encoding karaoke motion - continuing anyway\n"));
592 ret
= kate_ogg_encode_text(&k
, item
->t0
, item
->t1
, item
->text
, strlen(item
->text
)+1, &kate_op
);
594 opt
->error(_("Failed encoding lyrics - continuing anyway\n"));
597 ogg_stream_packetin(&ko
, &kate_op
);
598 ogg_packet_clear(&kate_op
);
601 int result
=ogg_stream_flush(&ko
,&ogk
);
603 ret
= oe_write_page(&ogk
, opt
->out
);
604 if(ret
!= ogk
.header_len
+ ogk
.body_len
)
606 opt
->error(_("Failed writing data to output stream\n"));
608 goto cleanup
; /* Bail */
611 bytes_written
+= ret
;
618 ret
= oe_write_page(&og
, opt
->out
);
619 if(ret
!= og
.header_len
+ og
.body_len
)
621 opt
->error(_("Failed writing data to output stream\n"));
623 goto cleanup
; /* Bail */
626 bytes_written
+= ret
;
628 if(ogg_page_eos(&og
))
635 /* if encoding lyrics, signal EOS and cleanup the kate state */
639 ret
= kate_ogg_encode_finish(&k
, vorbis_time
, &kate_op
);
641 opt
->error(_("Failed encoding Kate EOS packet\n"));
644 ogg_stream_packetin(&ko
,&kate_op
);
646 ogg_packet_clear(&kate_op
);
651 int result
= ogg_stream_pageout(&ko
,&og
);
654 ret
= oe_write_page(&og
, opt
->out
);
655 if(ret
!= og
.header_len
+ og
.body_len
)
657 opt
->error(_("Failed writing data to output stream\n"));
659 goto cleanup
; /* Bail */
662 bytes_written
+= ret
;
664 if(ogg_page_eos(&og
))
671 ret
= 0; /* Success. Set return value to 0 since other things reuse it
672 * for nefarious purposes. */
679 ogg_stream_clear(&ko
);
681 kate_info_clear(&ki
);
682 kate_comment_clear(&kc
);
687 if (opt
->with_skeleton
)
688 ogg_stream_clear(&so
);
690 ogg_stream_clear(&os
);
692 vorbis_block_clear(&vb
);
693 vorbis_dsp_clear(&vd
);
694 vorbis_info_clear(&vi
);
696 time_elapsed
= timer_time(timer
);
697 opt
->end_encode(opt
->filename
, time_elapsed
, opt
->rate
, samplesdone
, bytes_written
);
704 void update_statistics_full(char *fn
, long total
, long done
, double time
)
706 static char *spinner
="|/-\\";
707 static int spinpoint
= 0;
709 int minutes
=0,seconds
=0;
711 remain_time
= time
/((double)done
/(double)total
) - time
;
712 minutes
= ((int)remain_time
)/60;
713 seconds
= (int)(remain_time
- (double)((int)remain_time
/60)*60);
715 fprintf(stderr
, "\r");
716 fprintf(stderr
, _("\t[%5.1f%%] [%2dm%.2ds remaining] %c "),
717 done
*100.0/total
, minutes
, seconds
, spinner
[spinpoint
++%4]);
720 void update_statistics_notime(char *fn
, long total
, long done
, double time
)
722 static char *spinner
="|/-\\";
723 static int spinpoint
=0;
725 fprintf(stderr
, "\r");
726 fprintf(stderr
, _("\tEncoding [%2dm%.2ds so far] %c "),
727 ((int)time
)/60, (int)(time
- (double)((int)time
/60)*60),
728 spinner
[spinpoint
++%4]);
731 int oe_write_page(ogg_page
*page
, FILE *fp
)
734 written
= fwrite(page
->header
,1,page
->header_len
, fp
);
735 written
+= fwrite(page
->body
,1,page
->body_len
, fp
);
740 void final_statistics(char *fn
, double time
, int rate
, long samples
, long bytes
)
744 fprintf(stderr
, _("\n\nDone encoding file \"%s\"\n"), fn
);
746 fprintf(stderr
, _("\n\nDone encoding.\n"));
748 speed_ratio
= (double)samples
/ (double)rate
/ time
;
750 fprintf(stderr
, _("\n\tFile length: %dm %04.1fs\n"),
751 (int)(samples
/rate
/60),
753 floor(samples
/rate
/60)*60);
754 fprintf(stderr
, _("\tElapsed time: %dm %04.1fs\n"),
756 time
- floor(time
/60)*60);
757 fprintf(stderr
, _("\tRate: %.4f\n"), speed_ratio
);
758 fprintf(stderr
, _("\tAverage bitrate: %.1f kb/s\n\n"),
759 8./1000.*((double)bytes
/((double)samples
/(double)rate
)));
762 void final_statistics_null(char *fn
, double time
, int rate
, long samples
,
765 /* Don't do anything, this is just a placeholder function for quiet mode */
768 void update_statistics_null(char *fn
, long total
, long done
, double time
)
773 void encode_error(char *errmsg
)
775 fprintf(stderr
, "\n%s\n", errmsg
);
778 static void print_brconstraints(int min
, int max
)
780 if(min
> 0 && max
> 0)
781 fprintf(stderr
, _("(min %d kbps, max %d kbps)"), min
,max
);
783 fprintf(stderr
, _("(min %d kbps, no max)"), min
);
785 fprintf(stderr
, _("(no min, max %d kbps)"), max
);
787 fprintf(stderr
, _("(no min or max)"));
790 void start_encode_full(char *fn
, char *outfn
, int bitrate
, float quality
, int qset
,
791 int managed
, int min
, int max
)
795 fprintf(stderr
, _("Encoding %s%s%s to \n "
796 "%s%s%s \nat average bitrate %d kbps "),
797 fn
?"\"":"", fn
?fn
:_("standard input"), fn
?"\"":"",
798 outfn
?"\"":"", outfn
?outfn
:_("standard output"), outfn
?"\"":"",
800 print_brconstraints(min
,max
);
801 fprintf(stderr
, ", \nusing full bitrate management engine\n");
803 fprintf(stderr
, _("Encoding %s%s%s to \n %s%s%s \nat approximate bitrate %d kbps (VBR encoding enabled)\n"),
804 fn
?"\"":"", fn
?fn
:_("standard input"), fn
?"\"":"",
805 outfn
?"\"":"", outfn
?outfn
:_("standard output"), outfn
?"\"":"",
811 fprintf(stderr
, _("Encoding %s%s%s to \n %s%s%s \nat quality level %2.2f using constrained VBR "),
812 fn
?"\"":"", fn
?fn
:_("standard input"), fn
?"\"":"",
813 outfn
?"\"":"", outfn
?outfn
:_("standard output"), outfn
?"\"":"",
815 print_brconstraints(min
,max
);
816 fprintf(stderr
, "\n");
818 fprintf(stderr
, _("Encoding %s%s%s to \n %s%s%s \nat quality %2.2f\n"),
819 fn
?"\"":"", fn
?fn
:_("standard input"), fn
?"\"":"",
820 outfn
?"\"":"", outfn
?outfn
:_("standard output"), outfn
?"\"":"",
824 fprintf(stderr
, _("Encoding %s%s%s to \n %s%s%s \nusing bitrate management "),
825 fn
?"\"":"", fn
?fn
:_("standard input"), fn
?"\"":"",
826 outfn
?"\"":"", outfn
?outfn
:_("standard output"), outfn
?"\"":"");
827 print_brconstraints(min
,max
);
828 fprintf(stderr
, "\n");
833 void start_encode_null(char *fn
, char *outfn
, int bitrate
, float quality
, int qset
,
834 int managed
, int min
, int max
)