MediaCapture VideoStabilization 失败并显示 0xC00D4A3E

MediaCapture VideoStabilization fails with 0xC00D4A3E

我正在开发支持 VideoStabilization effect 的视频录制应用程序,但是当我开始录制时,我几乎立即通过 MediaCapture.Failed 事件收到以下信息:

The sample allocator is currently empty, due to outstanding requests. (0xC00D4A3E)

不过,只有当我使用效果推荐的配置时才会出现这种情况。如果我不调用 SetUpVideoStabilizationRecommendationAsync,它工作正常。

以下是我的设置方式:

    private MediaEncodingProfile _encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

    private async Task CreateVideoStabilizationEffectAsync()
    {
        var definition = new VideoStabilizationEffectDefinition();

        _videoStabilizationEffect = (VideoStabilizationEffect)await _mediaCapture.AddVideoEffectAsync(definition, MediaStreamType.VideoRecord);
        _videoStabilizationEffect.Enabled = true;

        await SetUpVideoStabilizationRecommendationAsync();
    }

    private async Task SetUpVideoStabilizationRecommendationAsync()
    {
        var properties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoRecord) as VideoEncodingProperties;
        var recommendation = _videoStabilizationEffect.GetRecommendedStreamConfiguration(_mediaCapture.VideoDeviceController, properties);

        if (recommendation.InputProperties != null)
        {
            await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, recommendation.InputProperties);
        }

        if (recommendation.OutputProperties != null)
        {
            _encodingProfile.Video = recommendation.OutputProperties;
        }
    }

    private async Task StartRecordingAsync()
    {
        var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("StableVideo.mp4", CreationCollisionOption.GenerateUniqueName);
        await _mediaCapture.StartRecordToStorageFileAsync(_encodingProfile, videoFile);
    }

GetRecommendedStreamConfiguration 方法的 desiredProperties 参数需要获取 MediaEncodingProfile ,这将在调用您选择的 MediaCapture.StartRecordTo* 时使用(即 "output properties" ) 看看你想要的 VideoEncodingProperties 是什么。

触发错误是因为 VideoDeviceController(即 "input properties")中的 VideoEncodingProperties 被传递了。如果您考虑一下,VideoDeviceController 的实例已经作为参数传递给方法,因此效果已经可以访问 properties var 中的信息;必须同时分别传递它们没有多大意义。相反,它需要的是关于另一个端点的信息。那有意义吗?至少这就是我试图合理化它的方式。

official SDK sample for VideoStabilization on the Microsoft github repo 显示了如何正确执行此操作:

    /// <summary>
    /// Configures the pipeline to use the optimal resolutions for VS based on the settings currently in use
    /// </summary>
    /// <returns></returns>
    private async Task SetUpVideoStabilizationRecommendationAsync()
    {
        Debug.WriteLine("Setting up VS recommendation...");

        // Get the recommendation from the effect based on our current input and output configuration
        var recommendation = _videoStabilizationEffect.GetRecommendedStreamConfiguration(_mediaCapture.VideoDeviceController, _encodingProfile.Video);

        // Handle the recommendation for the input into the effect, which can contain a larger resolution than currently configured, so cropping is minimized
        if (recommendation.InputProperties != null)
        {
            // Back up the current input properties from before VS was activated
            _inputPropertiesBackup = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoRecord) as VideoEncodingProperties;

            // Set the recommendation from the effect (a resolution higher than the current one to allow for cropping) on the input
            await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, recommendation.InputProperties);
            Debug.WriteLine("VS recommendation for the MediaStreamProperties (input) has been applied");
        }

        // Handle the recommendations for the output from the effect
        if (recommendation.OutputProperties != null)
        {
            // Back up the current output properties from before VS was activated
            _outputPropertiesBackup = _encodingProfile.Video;

            // Apply the recommended encoding profile for the output, which will result in a video with the same dimensions as configured
            // before VideoStabilization was added if an appropriate padded capture resolution was available. Otherwise, it will be slightly
            // smaller (due to cropping). This prevents upscaling back to the original size, which can result in a loss of quality
            _encodingProfile.Video = recommendation.OutputProperties;
            Debug.WriteLine("VS recommendation for the MediaEncodingProfile (output) has been applied");
        }
    }