Story
I am working on a smooth 60 FPS 1080p (Full HD) video transmission application that is encoded in x264, sends encoded data via LAN to a receiving device, which then decodes it using an OpenH264 decoder. I managed to get it to work, and it works fine and stable, but I found it very slow (about 20 FPS as opposed to the desired 60 FPS).
Problem
I did extensive testing and found that the problem is with the OpenH264 decoder.
The decoder uses the full core (25% of the total CPU usage) of my i5-2500 @ 3.9 GHz, which is too high. Despite the fact that the decoder is single-threaded, I tested the raw data in Media Player Classic, and its playback (at 60 FPS) led to 0.3% of CPU usage. (When switching the rendering mechanism to the "Old video recorder", it increased to 12.8-14.4% of the CPU usage - see Comments)
So my question is: What kind of optimizations can I do to speed up the decoding process and what am I doing wrong? I can not imagine that OpenH264 is so slow.
Additional Information
- The encoder can easily output 60 FPS 1080p using about 20% of the CPU.
- The connection is a wired LAN and can click> 10 MB / s, so there is no problem.
- Both the sender and receiver computers have 8 GB of RAM.
The code
The following is the C ++ code associated with the decoder:
ISVCDecoder *decoder; SBufferInfo bufferInfo; SDecodingParam decodingParam; uint8_t** yuvData; void init(int width, int height) { WelsCreateDecoder(&decoder); decodingParam = { 0 }; decodingParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC; decoder->Initialize(&decodingParam); bufferInfo = { 0 }; yuvData = new uint8_t*[3]; yuvData[0] = new uint8_t[width*height]; yuvData[1] = new uint8_t[width*height / 4]; yuvData[2] = new uint8_t[width*height / 4]; } bool decode(cont unsigned char* rawEncodedData, int rawEncodedDataLength, uint8_t** yuvData) { int err = decoder->DecodeFrameNoDelay(rawEncodedData, rawEncodedDataLength, yuvData, &bufferInfo); if(err != 0) { std::cout << "H264 decoding failed. Error code: " << err << "." << std::endl; return false; } return true; }
Rolling
source share