|
|
|
|
@ -24,6 +24,29 @@ void CallVideoDecoder::close() {
|
|
|
|
|
#endif |
|
|
|
|
m->format = {}; |
|
|
|
|
} |
|
|
|
|
call_video_caps CallVideoDecoder::capabilities() { |
|
|
|
|
call_video_caps caps{}; |
|
|
|
|
for (unsigned codec = 1; codec <= 2; ++codec) { |
|
|
|
|
unsigned profiles = 0; |
|
|
|
|
for (unsigned profile = 1; profile <= (codec == 1 ? 2u : 1u); ++profile) { |
|
|
|
|
uint8_t bytes[8192]; int size = call_video_probe_key(codec, profile, bytes, sizeof(bytes)); |
|
|
|
|
if (size < 0) continue; |
|
|
|
|
call_video_frame f{}; f.call_id = 1; f.flags = CALL_VIDEO_KEY; f.data = bytes; f.size = f.length = size; |
|
|
|
|
f.format = {1, 1280, 720, 30, 0, (uint8_t)codec, (uint8_t)(codec == 1 ? 31 : 93), 4000000, (uint8_t)profile}; |
|
|
|
|
CallVideoDecoder decoder; bool valid = true; |
|
|
|
|
for (unsigned i = 0; i < 4 && valid; ++i) { |
|
|
|
|
f.frame_id = i + 1; f.pts_us = 1000000 + i * 33333; |
|
|
|
|
QImage image; valid = decoder.decode(f, image); |
|
|
|
|
} |
|
|
|
|
if (valid) profiles |= profile; |
|
|
|
|
else DEBUG_WARN(DEBUG_CATEGORY_CALL, "video independent decoder probe failed codec=%u profile=%u", codec, profile); |
|
|
|
|
} |
|
|
|
|
if (profiles) caps.decode[codec - 1] = {1280, 720, 30, 1280 * 720 * 30, 4000000, |
|
|
|
|
(uint8_t)profiles, (uint8_t)(codec == 1 ? 31 : 93)}; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder probe codec=%u profiles=%u", codec, profiles); |
|
|
|
|
} |
|
|
|
|
return caps; |
|
|
|
|
} |
|
|
|
|
bool CallVideoDecoder::decode(const call_video_frame& f, QImage& image) { |
|
|
|
|
#ifdef HAVE_FFMPEG |
|
|
|
|
auto failed = [this, &f](const char* reason) { |
|
|
|
|
|