Broadway
Broadway copied to clipboard
Correct x264 encoder settings for Broadway to decode
Hi soliton4,
I have a question about the correct x264 settings for Broadway to decode. My current x264 settings are based on the advice of using FFMEG with Broadway:
The decoder expects an .mp4 file and does not support weighted prediction for P-frames and CABAC entropy encoding. To create such bitstreams use ffmpeg and x264 with the following command line options:
ffmpeg -y -i sourceFile -r 30000/1001 -b:a 2M -bt 4M -vcodec libx264 -pass 1 -coder 0 -bf 0 -flags -loop -wpredp 0 -an targetFile.mp4
So I translate the FFMPEG settings to x264 settings in the following way:
fps=29.97 ratetol=4.0 pass=1 no-cabac bframes=0 no-deblock weightp=0 tune=zerolatency profile=baseline
There is no problem if using FFMPEG with suggested settings for encoding. But encoding with x264 makes the decoded image blurred (pixelated), shown as follows:
A video clip of the same issue can be found here
https://www.dropbox.com/s/ey1u6ob92d94clq/exp2_.mp4?dl=0
Woud you please advise the correct settings of x264 encoder for Broadway to decode? Many thanks.
Best regards, Xiaosong
You need to send one nal unit at a time to player, sample code below.
function H264Player(){
console.log('using', this);
var p = new Player({
useWorker: true,
workerFile: "/Player/Decoder.js",
});
document.body.appendChild(p.canvas);
var parser = new nalParser(p);
this.play = function(buffer){
parser.parse(buffer);
};
}
var h264p = new H264Player();
h264p.play(<your array buffer here>);
function nalParser(player){
var bufferAr = [];
var concatUint8 = function(parAr) {
if (!parAr || !parAr.length){
return new Uint8Array(0);
};
if (parAr.length === 1){
return parAr[0];
};
var completeLength = 0;
var i = 0;
var l = parAr.length;
for (i; i < l; ++i){
completeLength += parAr[i].byteLength;
};
var res = new Uint8Array(completeLength);
var filledLength = 0;
for (i = 0; i < l; ++i){
res.set(new Uint8Array(parAr[i]), filledLength);
filledLength += parAr[i].byteLength;
};
return res;
};
this.parse = function(buffer){
if (!(buffer && buffer.byteLength)){
return;
};
var data = new Uint8Array(buffer);
var hit = function(subarray){
if (subarray){
bufferAr.push(subarray);
};
var buff = concatUint8(bufferAr);
player.decode(buff);
bufferAr = [];
};
var b = 0;
var lastStart = 0;
var l = data.length;
var zeroCnt = 0;
for (b = 0; b < l; ++b){
if (data[b] === 0){
zeroCnt++;
}else{
if (data[b] == 1){
if (zeroCnt >= 3){
if (lastStart < b - 3){
hit(data.subarray(lastStart, b - 3));
lastStart = b - 3;
}else if (bufferAr.length){
hit();
}
};
};
zeroCnt = 0;
};
};
if (lastStart < data.length){
bufferAr.push(data.subarray(lastStart));
};
};
}
Your encoder must use the Baseline profile of AVC/H.264, and must use CAVLC (Huffman-style) coding rather than CABAC (arithmetic) coding.
i dont think there is evidence for the claim that coding arithmetic would be involed in the bug described here. @OllieJones if you can further elaborate on how you come to the conclusion to blame encoding parameters, please do. otherwise dont confuse new users with noise please.