Story
pracuję na gładkiej 60 FPS 1080p (Full HD) stosowanie transferu wideo, który koduje w x264, wysyła zakodowane dane za pośrednictwem sieci LAN do urządzenia odbiorczego, który następnie dekoduje używając dekodera OpenH264. Udało mi się sprawić, że działa, i działa dobrze i jest stabilny, ale stwierdziłem, że jest bardzo powolny (około 20 FPS w przeciwieństwie do pożądanego 60 FPS).
Jak przyspieszyć OpenH264 za dekodera
Problem
Zrobiłem rozległe badania i okazało się, że problem leży po stronie dekodera OpenH264.
Dekoder wykorzystuje pełny rdzeń (25% całkowitego wykorzystania procesora) mojego i5-2500 @ 3,9 GHz, co jest o wiele za dużo. Mimo że dekoder jest jednowątkowy, przetestowałem surowe dane w odtwarzaczu Media Player Classic, a jego odtwarzanie (przy 60 FPS) spowodowało zużycie jedynie 0,3% procesora. (Po przełączeniu silnika renderującego na "Old Video Render" zwiększono zużycie procesora do 12,8-14,4% - patrz komentarze)
Moje pytanie brzmi: Jakie optymalizacje mogę zrobić, aby przyspieszyć proces dekodowania i co mam? Robię źle? Nie mogę sobie wyobrazić, że OpenH264 jest właśnie taki wolny.
Extra Info
- Koder jest w stanie łatwo wypchnąć 1080p 60 klatek na sekundę przy użyciu około 20% CPU.
- Połączenie jest przewodowe LAN i może przesłać> 10 MB/s, więc nie ma problemu.
- Komputery PC zarówno nadawcy, jak i odbiorcy mają 8 GB pamięci RAM.
Kod
Poniżej jest cały kod C++ związane z dekoderem:
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;
}
Czy próbowałeś profilowania kodu? – EvilTeach
Jeśli Media Player Classic używa 1,2% rdzenia, prawie na pewno rozładowuje to zadanie do sprzętowego dekodera wideo. –
Wypróbuj to w odtwarzaczu multimedialnym, a następnie zmierz wydajność odtwarzacza multimediów: https://www.pixelmetrics.com/Tips/VidBlank/MediaPlayer.php –