/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Diagnostics;
using Native = Interop.Recorder;
using NativeHandle = Interop.RecorderHandle;
namespace Tizen.Multimedia
{
///
/// Provides the ability to control video recording.
///
public partial class VideoRecorder : Recorder
{
private static NativeHandle CreateHandle(Camera camera)
{
if (camera == null)
{
throw new ArgumentNullException(nameof(camera));
}
Native.CreateVideo(camera.Handle, out var handle).
ThrowIfError("Failed to create video recorder.");
return handle;
}
private static void ThrowIfCodecAndFormatNotValid(RecorderVideoCodec videoCodec,
RecorderAudioCodec audioCodec, RecorderFileFormat fileFormat)
{
videoCodec.ThrowIfFormatNotSupported(fileFormat);
if (audioCodec != RecorderAudioCodec.None)
{
audioCodec.ThrowIfFormatNotSupported(fileFormat);
}
}
///
/// Initializes a new instance of the class with the specified camera, video codec and file format.
///
///
/// If the state of is ,
/// the will be changed to the recommended format for recording.\n
/// \n
/// The initial state of the Recorder will be
/// if the state of is or .
///
/// The camera object.
/// The codec for video encoding.
/// The format of result file.
/// http://tizen.org/feature/camera
/// An internal error occurred.
///
/// A required feature is not supported.\n
/// -or-\n
/// is not supported.\n
/// -or-\n
/// is not supported with the specified video codec.
///
///
/// is not valid.\n
/// -or-\n
/// is not valid.\n
/// -or-\n
/// is being used by another object.
///
/// has been disposed of.
/// is null.
///
///
///
///
///
public VideoRecorder(Camera camera, RecorderVideoCodec videoCodec, RecorderFileFormat fileFormat) :
this(camera, videoCodec, RecorderAudioCodec.None, fileFormat)
{
}
///
/// Initializes a new instance of the class with the specified camera, video codec,
/// audio codec and file format.
///
///
/// If the state of is ,
/// the will be changed to the recommended format for recording.\n
/// \n
/// The initial state of the Recorder will be
/// if the state of is or .
///
/// The camera object.
/// The codec for video encoding.
/// The codec for audio encoding.
/// The format of result file.
/// http://tizen.org/feature/camera
/// An internal error occurred.
///
/// A required feature is not supported.\n
/// -or-\n
/// is not supported.\n
/// -or-\n
/// is not supported.\n
/// -or-\n
/// is not supported with the specified video codec.
/// -or-\n
/// is not supported with the specified audio codec.
///
///
/// is not valid.\n
/// -or-\n
/// is not valid.\n
/// -or-\n
/// is not valid.
///
/// has been disposed of.
/// is null.
///
///
///
///
///
///
///
public VideoRecorder(Camera camera, RecorderVideoCodec videoCodec,
RecorderAudioCodec audioCodec, RecorderFileFormat fileFormat) : base(CreateHandle(camera))
{
SetFormatAndCodec(videoCodec, RecorderAudioCodec.None, fileFormat);
}
///
/// Sets the video codec and the file format for recording. Audio will not recorded.
///
/// The codec for video encoding.
/// The format of result file.
///
/// is not supported.\n
/// -or-\n
/// is not supported with the specified video codec.
///
///
/// is not valid.\n
/// -or-\n
/// is not valid.
///
///
///
///
///
///
public void SetFormatAndCodec(RecorderVideoCodec videoCodec, RecorderFileFormat fileFormat)
{
SetFormatAndCodec(videoCodec, RecorderAudioCodec.None, fileFormat);
}
///
/// Sets the video codec, audio codec and the file format for recording.
///
/// The codec for video encoding.
/// The codec for audio encoding.
/// The format of result file.
///
/// is not supported.\n
/// -or-\n
/// is not supported.\n
/// -or-\n
/// is not supported with the specified video codec.
/// -or-\n
/// is not supported with the specified audio codec.
///
///
/// is not valid.\n
/// -or-\n
/// is not valid.\n
/// -or-\n
/// is not valid.
///
///
///
///
///
///
///
///
public void SetFormatAndCodec(RecorderVideoCodec videoCodec, RecorderAudioCodec audioCodec, RecorderFileFormat fileFormat)
{
ThrowIfCodecAndFormatNotValid(videoCodec, audioCodec, fileFormat);
VideoCodec = videoCodec;
AudioCodec = audioCodec;
FileFormat = fileFormat;
}
#region Properties
private RecorderVideoCodec _videoCodec;
///
/// Gets the audio codec for encoding an audio stream.
///
public RecorderVideoCodec VideoCodec
{
get => _videoCodec;
internal set
{
Debug.Assert(Enum.IsDefined(typeof(RecorderVideoCodec), value));
ValidateVideoCodec(value);
Native.SetVideoEncoder(Handle, value).ThrowIfError("Failed to set video codec.");
_videoCodec = value;
}
}
///
/// Gets or sets the video recording motion rate.
///
///
/// The attribute is valid only in a video recorder.\n
/// If the rate is in range of 0-1, the video is recorded in a slow motion mode.\n
/// If the rate is bigger than 1, the video is recorded in a fast motion mode.\n
/// \n
/// To set, the recorder must be in the or the state.
///
/// The is less than or equal to 0.
/// The recorder is not in the valid state.
/// The recorder already has been disposed of.
public double VideoMotionRate
{
get
{
Native.GetMotionRate(Handle, out var val).ThrowIfError("Failed to get video motion rate.");
return val;
}
set
{
ValidateState(RecorderState.Idle, RecorderState.Ready);
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), value,
"Video Motion rate can't be less than zero.");
}
Native.SetMotionRate(Handle, value).
ThrowIfError("Failed to set video motion rate");
}
}
///
/// Gets or sets the orientation in the video metadata tag.
///
/// A that specifies the type of orientation.
/// is not valid.
/// The recorder already has been disposed of.
public Rotation VideoOrientationTag
{
get
{
Native.GetOrientationTag(Handle, out var val).ThrowIfError("Failed to get recorder orientation.");
return val;
}
set
{
ValidationUtil.ValidateEnum(typeof(Rotation), value, nameof(value));
Native.SetOrientationTag(Handle, value).
ThrowIfError("Failed to set recorder orientation");
}
}
///
/// Gets or sets the resolution of the video recording.
///
///
/// To set, the recorder must be in the or the state.
///
/// Width or height of is less than or equal to zero.
/// is not supported.
/// The recorder is not in the valid state.
/// The recorder already has been disposed of.
///
public Size VideoResolution
{
get
{
Native.GetVideoResolution(Handle, out var width, out var height).
ThrowIfError("Failed to get camera video resolution");
return new Size(width, height);
}
set
{
ValidateState(RecorderState.Idle, RecorderState.Ready);
if (value.Width <= 0 || value.Height <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), value,
"Resolution can't be less than or equal to zero.");
}
var ret = Native.SetVideoResolution(Handle, value.Width, value.Height);
if (ret == RecorderErrorCode.InvalidParameter)
{
throw new NotSupportedException($"Resolution({value.ToString()}) is not supported.");
}
ret.ThrowIfError("Failed to set video resolution.");
}
}
///
/// Gets or sets the bitrate of the video encoder in bits per second.
///
///
/// To set, the recorder must be in the or state.
///
/// is less than or equal to zero.
/// The recorder is not in the valid state.
/// The recorder already has been disposed of.
public int VideoBitRate
{
get
{
Native.GetVideoEncoderBitrate(Handle, out var val).ThrowIfError("Failed to get video bitrate.");
return val;
}
set
{
ValidateState(RecorderState.Idle, RecorderState.Ready);
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), value,
"Bit rate can't be less than or equal to zero.");
}
Native.SetVideoEncoderBitrate(Handle, value).
ThrowIfError("Failed to set video bitrate");
}
}
#endregion
}
}