2016-09-02 56 views
8

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; 
} 
+1

Czy próbowałeś profilowania kodu? – EvilTeach

+4

Jeśli Media Player Classic używa 1,2% rdzenia, prawie na pewno rozładowuje to zadanie do sprzętowego dekodera wideo. –

+0

Wypróbuj to w odtwarzaczu multimedialnym, a następnie zmierz wydajność odtwarzacza multimediów: https://www.pixelmetrics.com/Tips/VidBlank/MediaPlayer.php –

Odpowiedz

1

stosunkowo un-zoptymalizowany procesor oparty dekoder H.264 może być łatwo, że wolno. Jeśli jesteś na komputerze i masz sprzętowy dekoder H.264 - równie dobrze możesz z niego korzystać.

Spróbowałbym: https://software.intel.com/en-us/media-sdk-support/code-samples

+0

Przejście do dekodera H.264 FFmpeg rozwiązało problem. Wciąż mam od 20 do 35% użycia procesora, ale obejmuje to również kilka innych procesów. Okazuje się, że dekoder OpenH264 jest tak powolny ... – Roland