Broadway icon indicating copy to clipboard operation
Broadway copied to clipboard

Correct x264 encoder settings for Broadway to decode

Open xiaoyaoth opened this issue 8 years ago • 3 comments

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: exp2_ 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

xiaoyaoth avatar Mar 11 '16 05:03 xiaoyaoth

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));
    };
  };
}

amitv87 avatar Sep 30 '16 13:09 amitv87

Your encoder must use the Baseline profile of AVC/H.264, and must use CAVLC (Huffman-style) coding rather than CABAC (arithmetic) coding.

OllieJones avatar Jul 20 '18 21:07 OllieJones

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.

soliton4 avatar Jul 20 '18 21:07 soliton4