mattdesl / mp4-wasm-encoder

https://mattdesl.github.io/mp4-wasm-encoder/
MIT License
74 stars 2 forks source link

Use WebCodecs for a faster encoding! #1

Open dalecurtis opened 3 years ago

dalecurtis commented 3 years ago

The README says to create an issue for suggestions on how to make it faster :)

https://web.dev/webcodecs/ offers a way to directly use the hardware encoders for the various codecs that Chrome supports. It's in origin trial right now, so feedback is appreciated!

https://github.com/WICG/web-codecs https://bugs.chromium.org/p/chromium/issues/entry?components=Blink%3eMedia%3eWebCodecs

mattdesl commented 3 years ago

Thanks Dale – I'd be really interested in using WebCodecs (I have a webcodecs branch here testing vp9) but I felt blocked by two problems:

dalecurtis commented 3 years ago
mattdesl commented 3 years ago

Thanks! I'm actually not using ffmpeg here, but small open source C libraries, minimp4 (for turning h264 frames into mp4 container) and minih264 (for encoding YUV to h264).

I don't know much about AnnexB vs AVCC, but to use the minimp4 library I have to send it chunks of NAL data to mux into a mp4. I guess that NAL data is just the same as the AnnexB data?

dalecurtis commented 3 years ago

The second parameter of the output callback is a VideoDecoderConfig object. The description field on that object should have the NAL chunks you need to hand to minimp4. The payload is already in AVC format so it should be ready to insert into an MP4.

mattdesl commented 3 years ago

Ok, got it all working after a bit of a struggle. Had to convert the frames from AVC to AnnexB on the fly, for minimp4 to accept them. Presumably this will be easier once AnnexB lands in WebCodecs.

Now with WebCodecs instead of minih264 encoder, it's really fast (encoding ~300 frames in 5 seconds, instead of 300 frames in ~14 seconds).

So other than the quality issues, it seems to be working pretty well! You can see my code here:

https://github.com/mattdesl/mp4-h264/blob/cfd8e1ca99c88f2af9d6ca07d0531324587618cb/test/webcodecs.html

dalecurtis commented 3 years ago

Awesome, glad it's working! Sorry it's a bit complicated to get going.

What platform are you testing on? We'll want to track your issues in the Chromium tracker so they don't get forgotten. @chcunningham

mattdesl commented 3 years ago

Alright thanks! I think this might have actually just been my own code not setting the size correctly, so it was sending lower quality frames, although I'm still noticing a few issues here and there and overall the image appears more faded/muted in color. I'll try to log them in the tracker as I see them.

dalecurtis commented 3 years ago

Probably color space information isn't correctly passed to the encoder somewhere (could be on our side). If you have a repro case with a comparison shot we can dig further.