summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordknn <yoann.blein@free.fr>2012-08-16 21:52:56 (GMT)
committerdknn <yoann.blein@free.fr>2012-09-22 09:32:38 (GMT)
commitdce09fe24d55d67f60d7bc691e285897f1d64fc2 (patch)
treef064c11c7c25a647a73c42d01e2cb836ea601bb3 /Swiften/ScreenSharing/VP8Decoder.cpp
parent867a950d5b3eb1422051a57c2533509188014b1a (diff)
downloadswift-contrib-dce09fe24d55d67f60d7bc691e285897f1d64fc2.zip
swift-contrib-dce09fe24d55d67f60d7bc691e285897f1d64fc2.tar.bz2
Add error resilience on decoder side
Diffstat (limited to 'Swiften/ScreenSharing/VP8Decoder.cpp')
-rw-r--r--Swiften/ScreenSharing/VP8Decoder.cpp37
1 files changed, 33 insertions, 4 deletions
diff --git a/Swiften/ScreenSharing/VP8Decoder.cpp b/Swiften/ScreenSharing/VP8Decoder.cpp
index 2634cc5..90f5101 100644
--- a/Swiften/ScreenSharing/VP8Decoder.cpp
+++ b/Swiften/ScreenSharing/VP8Decoder.cpp
@@ -19,7 +19,7 @@ inline int clamp8(int v)
VP8Decoder::VP8Decoder()
: VideoDecoder(),
- codecInterface(vpx_codec_vp8_dx()), codecFlags(0)
+ codecInterface(vpx_codec_vp8_dx()), codecFlags(0), refFrame(0)
{
SWIFT_LOG(debug) << "VP8 Decoder:" << vpx_codec_iface_name(codecInterface) << std::endl;
@@ -28,6 +28,11 @@ VP8Decoder::VP8Decoder()
VP8Decoder::~VP8Decoder()
{
+ vpx_codec_destroy(&codecContext);
+ if (refFrame) {
+ vpx_img_free(&refFrame->img);
+ delete refFrame;
+ }
}
void VP8Decoder::updateCodecConfig()
@@ -53,10 +58,34 @@ void VP8Decoder::decodeFrame(const std::vector<uint8_t>& frame, int pictureID)
}
vpx_codec_iter_t iter = NULL;
- vpx_image_t* img;
- while ((img = vpx_codec_get_frame(&codecContext, &iter))) {
- Image rgbImg = convertYV12toRGB(img);
+ vpx_image_t* decodedImg;
+ while ((decodedImg = vpx_codec_get_frame(&codecContext, &iter))) {
+ Image rgbImg = convertYV12toRGB(decodedImg);
onNewImageAvailable(rgbImg);
+ // Restore ref from last save if corrupted, else save the ref
+ int corrupted = 0;
+ vpx_codec_control(&codecContext, VP8D_GET_FRAME_CORRUPTED, &corrupted);
+ if (corrupted) {
+ vpx_codec_control(&codecContext, VP8_SET_REFERENCE, refFrame);
+ } else {
+ // Re-alloc the image ref if the format has changed
+ if (refFrame && (decodedImg->d_w != refFrame->img.d_w
+ || decodedImg->d_h != refFrame->img.d_h
+ || decodedImg->fmt != refFrame->img.fmt)) {
+ vpx_img_free(&refFrame->img);
+ delete refFrame;
+ refFrame = 0;
+ }
+ if (!refFrame) {
+ refFrame = new vpx_ref_frame_t;
+ refFrame->frame_type = VP8_LAST_FRAME;
+ unsigned int align = 1;
+ if (decodedImg->d_w % 32 == 0)
+ align = 32;
+ vpx_img_alloc(&refFrame->img, decodedImg->fmt, decodedImg->d_w, decodedImg->d_h, align);
+ }
+ vpx_codec_control(&codecContext, VP8_COPY_REFERENCE, refFrame);
+ }
}
}