//
// DVD-HQ Bitrate Calculator v4
//
// All scripts (c) Rui del-Negro 2008
//
// If you use any part of them, give proper credit. If you want to
// use them commercially (this includes any site that is paid or
// has advertising), you must obtain permission from the author.
// This notice must be included in all derivative work.
//
// http://DVD-HQ.info/
//

// Still undergoing some tweaking; looks a bit messy






function brc_error()
{
 document.forms["brc_output"].brc_o_status.value=" INVALID SETTINGS ";
 document.forms["brc_output"].brc_o_ratecontrol.value=" ";
 document.forms["brc_output"].brc_o_brmax.value=" ";
 document.forms["brc_output"].brc_o_bravg.value=" ";
 document.forms["brc_output"].brc_o_brmin.value=" ";
 document.forms["brc_output"].brc_o_ipic.value=" ";
 document.forms["brc_output"].brc_o_ppic.value=" ";
 document.forms["brc_output"].brc_o_bpic.value=" ";
 document.forms["brc_output"].brc_o_goplimit.value=" ";
 document.forms["brc_output"].brc_o_vsize.value=" ";
 document.forms["brc_output"].brc_o_asize.value=" ";
 document.forms["brc_output"].brc_o_osize.value=" ";
 document.forms["brc_output"].brc_o_rsize.value=" ";

}






function brc_savepreset()
{

var new_url = "http://dvd-hq.info/bitrate_calculator.php?";

new_url = new_url + "length=";
new_url = new_url + parseInt(document.forms['brc_input'].brc_i_length.value);

new_url = new_url + "&vformat=";
new_url = new_url + document.forms['brc_input'].brc_i_vformat[document.forms['brc_input'].brc_i_vformat.selectedIndex].value;

new_url = new_url + "&audiobr=";
new_url = new_url + parseInt(document.forms['brc_input'].brc_i_audiobr.value);

new_url = new_url + "&astreams=";
new_url = new_url + document.forms['brc_input'].brc_i_astreams.selectedIndex;

new_url = new_url + "&ratemode=";
new_url = new_url + document.forms['brc_input'].brc_i_ratemode[document.forms['brc_input'].brc_i_ratemode.selectedIndex].value;

new_url = new_url + "&motion=";
new_url = new_url + document.forms['brc_input'].brc_i_motion[document.forms['brc_input'].brc_i_motion.selectedIndex].value;

new_url = new_url + "&scenedetect=";
new_url = new_url + document.forms['brc_input'].brc_i_scenedetect[document.forms['brc_input'].brc_i_scenedetect.selectedIndex].value;

new_url = new_url + "&brlimit=";
new_url = new_url + parseInt(document.forms['brc_input'].brc_i_brlimit.value);

new_url = new_url + "&discsize=";
new_url = new_url + parseInt(document.forms['brc_input'].brc_i_discsize.value);

new_url = new_url + "&otherassets=";
new_url = new_url + parseInt(document.forms['brc_input'].brc_i_otherassets.value);


new_url = new_url + "#Calculator";


alert ("After you close this message, the calculator will be reloaded with the current settings encoded into the address. Wait for it to finish reloading and then bookmark the resulting page (or add it to your \"Favourites\").\n\nYou can create as many presets as you want, but remember to give the bookmarks descriptive titles, so you can distinguish them later.");

location.href=new_url;


}








function brc_loadquery()
{

 document.forms["brc_output"].brc_o_status.value=" READING QUERY ";

var query_arg = new Array();

var query = document.location.search.substring(1);
var parms = query.split('&');

for (var i=0; i<parms.length; i++)
{
 var pos = parms[i].indexOf('=');
 if (pos > 0)
 {
  var key = parms[i].substring(0,pos);
  var val = parms[i].substring(pos+1);
  query_arg[key] = val;
 }
}


// SET VIDEO LENGTH
document.forms["brc_output"].brc_o_status.value=" READING LENGTH ";

if (query_arg['length'])
{
 if (query_arg['length']<1000)
 {
  document.forms['brc_input'].brc_i_length.value = query_arg['length'];
 }
}

// SET VIDEO FORMAT
document.forms["brc_output"].brc_o_status.value=" READING FORMAT ";

if (query_arg['vformat'])
{
 if (query_arg['vformat'].toUpperCase()=='PAL')
 {
  document.forms['brc_input'].brc_i_vformat.selectedIndex=0;
 }
 if (query_arg['vformat'].toUpperCase()=='NTSC')
 {
  document.forms['brc_input'].brc_i_vformat.selectedIndex=1;
 }
}

// SET AUDIO BITRATE
document.forms["brc_output"].brc_o_status.value=" READING AUDIO ";

if (query_arg['audiobr'])
{
 if (query_arg['audiobr']<1000000)
 {
  document.forms['brc_input'].brc_i_aformat[1].checked='true';
  document.forms['brc_input'].brc_i_audiobr.value=query_arg['audiobr'];
 }
}


// SET AUDIO STREAMS
document.forms["brc_output"].brc_o_status.value=" READING STREAMS ";

if (query_arg['astreams'])
{
 if (query_arg['astreams']<document.forms['brc_input'].brc_i_astreams.length)
 {
  document.forms['brc_input'].brc_i_astreams.selectedIndex=query_arg['astreams'];
 }
}

// SET RATE CONTROL
document.forms["brc_output"].brc_o_status.value=" READING RATE ";

if (query_arg['ratemode'])
{
 if (query_arg['ratemode'].toUpperCase()=='AUTO' ||
     query_arg['ratemode'].toUpperCase()=='AUTOMATIC')
 {
  document.forms['brc_input'].brc_i_ratemode.selectedIndex=0;
 }

 if (query_arg['ratemode'].toUpperCase()=='CBR'||
     query_arg['ratemode'].toUpperCase()=='FORCECBR')
 {
  document.forms['brc_input'].brc_i_ratemode.selectedIndex=1;
 }
}


// SET SCENE MOTION
document.forms["brc_output"].brc_o_status.value=" READING MOTION ";

if (query_arg['motion'])
{
 if (query_arg['motion'].toUpperCase()=='HIGH' ||
     query_arg['motion'].toUpperCase()=='HEAVY' || 
     query_arg['motion'].toUpperCase()=='MIXED')
 {
  document.forms['brc_input'].brc_i_motion.selectedIndex=0;
 }

 if (query_arg['motion'].toUpperCase()=='LOW' ||
     query_arg['motion'].toUpperCase()=='LIGHT' ||
     query_arg['motion'].toUpperCase()=='NONE')
 {
  document.forms['brc_input'].brc_i_motion.selectedIndex=1;
 }
}


// SET SCENE DETECTION
document.forms["brc_output"].brc_o_status.value=" READING SCENE ";

if (query_arg['scenedetect'])
{
 if (query_arg['scenedetect'].toUpperCase()=='ACTIVE' ||
     query_arg['scenedetect'].toUpperCase()=='ON' ||
     query_arg['scenedetect'].toUpperCase()=='ENABLED')
 {
  document.forms['brc_input'].brc_i_scenedetect.selectedIndex=0;
 }

 if (query_arg['scenedetect'].toUpperCase()=='INACTIVE' ||
     query_arg['scenedetect'].toUpperCase()=='OFF' ||
     query_arg['scenedetect'].toUpperCase()=='DISABLED')
 {
  document.forms['brc_input'].brc_i_scenedetect.selectedIndex=1;
 }
}


// SET BITRATE LIMIT
document.forms["brc_output"].brc_o_status.value=" READING VIDEO ";

if (query_arg['brlimit'])
{
 if(query_arg['brlimit']<10000000)
 {
  document.forms['brc_input'].brc_i_brformat[1].checked='true';
  document.forms['brc_input'].brc_i_brlimit.value=query_arg['brlimit'];
 }
}


// SET MEDIA SIZE
document.forms["brc_output"].brc_o_status.value=" READING MEDIA ";

if (query_arg['discsize'])
{
 if (query_arg['discsize']<10000000)
 {
  document.forms['brc_input'].brc_i_disctype[1].checked='true';
  document.forms['brc_input'].brc_i_discsize.value=query_arg['discsize'];
 }
}


// SET OTHER ASSETS
document.forms["brc_output"].brc_o_status.value=" READING OTHER ";

if (query_arg['otherassets'])
{
 if (query_arg['otherassets']<1000000)
 {
  document.forms['brc_input'].brc_i_otherassets.value = query_arg['otherassets'];
 }
}

}









function brc_calculate()
{


document.forms["brc_output"].brc_o_status.value=" INITIALISING ";

var brc_c_temp;

var brc_c_length;
var brc_c_videobr;
var brc_c_audiobr;
var brc_c_fps;
var brc_c_brlimit;
var brc_c_goplimit;
var brc_c_gopsize;
var brc_c_shortgop;
var brc_c_maxgop;
var brc_c_astreams;
var brc_c_freespace;
var brc_c_forceCBR;

var brc_c_asize;
var brc_c_vsize;
var brc_c_rsize;

var brc_c_ratemode;

var brc_c_brmax;
var brc_c_bravg;
var brc_c_brmin;

var brc_c_ipic;
var brc_c_ppic;
var brc_c_bpic;

var brc_c_ipicmin;
var brc_c_ppicmin;
var brc_c_bpicmin;

var brc_c_ipicmax;
var brc_c_ppicmax;
var brc_c_bpicmax;

var brc_c_margin=1.03; // safety margin (1=0%, 1.05 = 5%, etc.) using 3% since bitrates are rounded down


document.forms["brc_output"].brc_o_status.value=" LENGTH ";

if (document.forms["brc_input"].brc_i_length.value<1) document.forms["brc_input"].brc_i_length.value="1 ";

brc_c_length=document.forms["brc_input"].brc_i_length.value*60; // convert minutes to seconds
document.forms["brc_input"].brc_i_length.value=document.forms["brc_input"].brc_i_length.value*1.0+' ';





document.forms["brc_output"].brc_o_status.value=" VIDEO FORMAT ";

if (document.forms["brc_input"].brc_i_vformat.value=="PAL") // PAL
{
 brc_c_goplimit=15.0;
 brc_c_fps=25;
}
else if (document.forms["brc_input"].brc_i_vformat.value=="NTSC") // NTSC
{
 brc_c_goplimit=18.0;
 brc_c_fps=29.97;
}
else // this should never happen
{
 brc_error();
 return;
}




document.forms["brc_output"].brc_o_status.value=" AUDIO FORMAT ";


if (document.forms["brc_input"].brc_i_aformat[0].checked) // PRESET
{
 brc_c_audiobr=document.forms["brc_input"].brc_i_audiobrpreset.value;
}
else // manual
{
 brc_c_audiobr=document.forms["brc_input"].brc_i_audiobr.value*1.0;
}

if (brc_c_audiobr<0) brc_c_audiobr=0;
document.forms["brc_input"].brc_i_audiobr.value=brc_c_audiobr+' '; // update


brc_c_astreams=document.forms["brc_input"].brc_i_astreams.value*1.0;




document.forms["brc_output"].brc_o_status.value=" RATE CONTROL ";


if (document.forms["brc_input"].brc_i_ratemode.value=="CBR") // Force CBR
{
 brc_c_forceCBR=true;
}
else
{
 brc_c_forceCBR=false;
}




document.forms["brc_output"].brc_o_status.value=" OTHER ASSETS ";


brc_c_otherassets=document.forms["brc_input"].brc_i_otherassets.value*1.0;

if (brc_c_otherassets<0) brc_c_otherassets=0;
document.forms["brc_input"].brc_i_otherassets.value=brc_c_otherassets+' '; // update


document.forms["brc_output"].brc_o_osize.value=" "+brc_c_otherassets+' ';





document.forms["brc_output"].brc_o_status.value=" DISC TYPE ";



if (document.forms["brc_input"].brc_i_disctype[0].checked) // PRESET
{
 brc_c_freespace=document.forms["brc_input"].brc_i_disctypepreset.value*1.0;
}
else // manual
{
 brc_c_freespace=document.forms["brc_input"].brc_i_discsize.value*1.0;
}


if (brc_c_freespace<0) brc_c_freespace=0;
document.forms["brc_input"].brc_i_discsize.value=brc_c_freespace+' '; // update


brc_c_freespace-=brc_c_otherassets; // retirar assets




document.forms["brc_output"].brc_o_status.value=" RATE LIMIT ";


if (document.forms["brc_input"].brc_i_brformat[0].checked) // VCD
{
 brc_c_brlimit=document.forms["brc_input"].brc_i_brlimitpreset.value;
}
else // manual
{
 brc_c_brlimit=document.forms["brc_input"].brc_i_brlimit.value*1.0
}

if (brc_c_brlimit<0) brc_c_brlimit=0;
document.forms["brc_input"].brc_i_brlimit.value=brc_c_brlimit+' '; // update




document.forms["brc_output"].brc_o_status.value=" SIZE ";


brc_c_asize=brc_c_length*(brc_c_audiobr/8.192)*brc_c_astreams; // space taken by audio in kB (kB1024 / kb1000)

brc_c_temp=brc_c_asize/1024+0.5; // convert to MB
brc_c_temp-=(brc_c_temp%1);
if (brc_c_temp<0){ brc_error(); return;}
document.forms["brc_output"].brc_o_asize.value=" "+brc_c_temp+' ';	// show as MB, no decimal places




document.forms["brc_output"].brc_o_status.value=" BITRATE ";


brc_c_brmax=(brc_c_brlimit-(brc_c_audiobr*brc_c_astreams))/brc_c_margin;  // brmax
brc_c_brmax=brc_c_brmax-(brc_c_brmax%50);

brc_c_bravg=((brc_c_freespace*1024-brc_c_asize)*8)/brc_c_length/brc_c_margin;  // bravg
brc_c_bravg=brc_c_bravg-(brc_c_bravg%50);

brc_c_brmin=brc_c_bravg/2.5  // brmin
brc_c_brmin=brc_c_brmin-(brc_c_brmin%50);


if (brc_c_brmax<=brc_c_bravg)
{
 brc_c_bravg=brc_c_brmax;
 brc_c_forceCBR=true;
}

if (brc_c_forceCBR)
{
 document.forms["brc_output"].brc_o_ratecontrol.value=" CBR ";
 brc_c_brmax=brc_c_bravg;
 brc_c_brmin=brc_c_bravg;
}
else
{
 document.forms["brc_output"].brc_o_ratecontrol.value=" 2-pass VBR ";
}

if (brc_c_bravg<=0)
{
 brc_error();
 return;
}
else
{
 document.forms["brc_output"].brc_o_brmax.value=" "+brc_c_brmax+' ';
 document.forms["brc_output"].brc_o_bravg.value=" "+brc_c_bravg+' ';
 document.forms["brc_output"].brc_o_brmin.value=" "+brc_c_brmin+' ';
}

brc_c_vsize=brc_c_bravg*1024/8*brc_c_length;

brc_c_temp=brc_c_vsize/1024/1024+0.5;
brc_c_temp-=(brc_c_temp%1);
if (brc_c_temp<0) { brc_error(); return;}
document.forms["brc_output"].brc_o_vsize.value=" "+brc_c_temp+' ';

brc_c_temp=brc_c_freespace-document.forms["brc_output"].brc_o_vsize.value-document.forms["brc_output"].brc_o_asize.value
if (brc_c_temp<0) { brc_error(); return;}
document.forms["brc_output"].brc_o_rsize.value=" "+brc_c_temp+' ';



document.forms["brc_output"].brc_o_status.value=" GOP SIZE ";


// determine GOP size

brc_c_shortgop=brc_c_goplimit;

if (document.forms["brc_input"].brc_i_scenedetect.value=="Inactive") // if scene detect is disabled, shorten the GOPs
{
 brc_c_shortgop=(brc_c_fps/5)+0.5 // calculate a short GOP (1/5th of a second) and round it
 brc_c_shortgop-=brc_c_shortgop%1;  
}


if (brc_c_shortgop<brc_c_goplimit) // GOP limit is defined by the standard, GOP max is our target sub-GOP size
{
 brc_c_gopmax=brc_c_shortgop;
}
else
{
 brc_c_gopmax=brc_c_goplimit;
}


document.forms["brc_output"].brc_o_goplimit.value=" "+brc_c_goplimit+" ";





brc_c_ipic=1; // start with a single GOP

brc_c_ppic=brc_c_goplimit; // start high, reduce later

brc_c_bpic=0; // start with no B-pictures;




document.forms["brc_output"].brc_o_status.value=" B-PICTURES ";

if (document.forms['brc_input'].brc_i_motion.selectedIndex==1) brc_c_bpic++; // if low motion, add a B-picture

if (brc_c_bravg<5000) brc_c_bpic++; // add a B if bitrate is under 5000

if (brc_c_bravg<3000) brc_c_bpic++; // add a B if bitrate is under 3000

if (brc_c_bravg<2000) brc_c_bpic++; // add a B if bitrate is under 2000

document.forms["brc_output"].brc_o_bpic.value=" "+brc_c_bpic;





document.forms["brc_output"].brc_o_status.value=" P-PICTURES ";

// reduce the number of P-pictures until it fits a sub-GOP

while (true)
{
 brc_c_goplength=(brc_c_ipic)+(brc_c_ipic*brc_c_ppic)+(brc_c_ipic*brc_c_ppic*brc_c_bpic)+(brc_c_ipic*brc_c_bpic);

 if (brc_c_goplength<=brc_c_gopmax)
 {
  break;	// if it fits, break out of loop
 }
 else
 {
  brc_c_ppic-=1; // otherwise, subtract one P-picture
 }

 if (brc_c_ppic<0) // are we below zero? shouldn't happen
 {
  brc_error();
  return;
 }

}

document.forms["brc_output"].brc_o_ppic.value=" "+brc_c_ppic;






document.forms["brc_output"].brc_o_status.value=" I-PICTURES ";

// increase the number of I-pictures to use sub-GOPs

while (true)
{

 brc_c_goplength=(brc_c_ipic)+(brc_c_ipic*brc_c_ppic)+(brc_c_ipic*brc_c_ppic*brc_c_bpic)+(brc_c_ipic*brc_c_bpic);

 if (brc_c_goplength>brc_c_goplimit)
 {
  brc_c_ipic-=1; // subtract last I picture
  break;	 // if it fits, break out of loop
 }
 else
 {
  brc_c_ipic+=1; // otherwise, add one I-picture
 }

}

document.forms["brc_output"].brc_o_ipic.value=" "+brc_c_ipic;




document.forms["brc_output"].brc_o_status.value=" OK ";

}





brc_loadquery(); // read query values if passed

brc_calculate(); // init

