/// <summary> /// Initializes a new instance of the MediaCodec class. /// </summary> /// <feature>http://tizen.org/feature/multimedia.media_codec</feature> /// <exception cref="NotSupportedException">The required feature is not supported.</exception> /// <since_tizen> 3 </since_tizen> public MediaCodec() { Native.Create(out _handle).ThrowIfFailed("Failed to create media codec."); RegisterInputProcessed(); RegisterErrorOccurred(); }
private static void LoadSupportedCodec() { var videoCodecList = new List <MediaFormatVideoMimeType>(); var audioCodecList = new List <MediaFormatAudioMimeType>(); Native.SupportedCodecCallback cb = (codecType, _) => { if ((codecType & CodecKindMask) == CodecKindVideo) { MediaFormatVideoMimeType mimeType = 0; if (TryGetMimeTypeFromCodecType(codecType, ref mimeType)) { videoCodecList.Add(mimeType); } } else { MediaFormatAudioMimeType mimeType = 0; if (TryGetMimeTypeFromCodecType(codecType, ref mimeType)) { audioCodecList.Add(mimeType); } } return(true); }; Native.ForeachSupportedCodec(cb, IntPtr.Zero).ThrowIfFailed("Failed to get supported codec."); _supportedVideoCodecs = videoCodecList.AsReadOnly(); _supportedAudioCodecs = audioCodecList.AsReadOnly(); }
private MediaCodecTypes GetCodecType(int mimeType, bool isEncoder) { int codecType = mimeType & CodecTypeMask; Native.GetSupportedType(_handle, codecType, isEncoder, out int value). ThrowIfFailed("Failed to get supported media codec type."); return((MediaCodecTypes)value); }
private void DoConfigure(int codecType, bool encoder, MediaCodecTypes supportType) { Debug.Assert(Enum.IsDefined(typeof(SupportedCodecType), codecType)); int flags = (int)(encoder ? MediaCodecCodingType.Encoder : MediaCodecCodingType.Decoder); flags |= (int)supportType; Native.Configure(_handle, codecType, flags).ThrowIfFailed("Failed to configure media codec."); }
private MediaCodecTypes GetCodecType <T>(T mimeType, Type type, bool isEncoder) { dynamic changedType = Convert.ChangeType(mimeType, type); int codecType = TypeConverter.ToNative(changedType); Native.GetSupportedType(_handle, codecType, isEncoder, out int value). ThrowIfFailed("Failed to get supported media codec type."); return((MediaCodecTypes)value); }
private void RegisterErrorOccurred() { _errorCb = (errorCode, _) => { MediaCodecError error = (Enum.IsDefined(typeof(MediaCodecError), errorCode)) ? (MediaCodecError)errorCode : MediaCodecError.InternalError; ErrorOccurred?.Invoke(this, new MediaCodecErrorOccurredEventArgs(error)); }; Native.SetErrorCb(_handle, _errorCb).ThrowIfFailed("Failed to set error callback."); }
/// <summary> /// Adds the packet to the internal queue of the codec. /// </summary> /// <param name="packet">The packet to be encoded or decoded.</param> /// <feature>http://tizen.org/feature/multimedia.media_codec</feature> /// <exception cref="NotSupportedException">The required feature is not supported.</exception> /// <exception cref="ArgumentNullException"><paramref name="packet"/> is null.</exception> /// <exception cref="InvalidOperationException">The current codec is not prepared yet.</exception> /// <remarks>Any attempts to modify the packet will fail until the <see cref="InputProcessed"/> event for the packet is invoked.</remarks> /// <since_tizen> 3 </since_tizen> public void ProcessInput(MediaPacket packet) { ValidateNotDisposed(); if (packet == null) { throw new ArgumentNullException(nameof(packet)); } MediaPacket.Lock packetLock = MediaPacket.Lock.Get(packet); Native.Process(_handle, packetLock.GetHandle(), 0).ThrowIfFailed("Failed to process input.");; }
private void RegisterBufferStatusChanged() { _bufferStatusCb = (statusCode, _) => { Debug.Assert(Enum.IsDefined(typeof(MediaCodecStatus), statusCode), $"{ statusCode } is not defined in MediaCodecStatus!"); BufferStatusChanged?.Invoke(this, new BufferStatusChangedEventArgs(statusCode)); }; Native.SetBufferStatusCb(_handle, _bufferStatusCb). ThrowIfFailed("Failed to set buffer status callback."); }
/// <summary> /// Releases the resources used by the <see cref="MediaCodec"/> object. /// </summary> /// <param name="disposing"> /// true to release both managed and unmanaged resources; false to release only unmanaged resources. /// </param> /// <since_tizen> 3 </since_tizen> protected virtual void Dispose(bool disposing) { if (!_isDisposed) { if (_handle != IntPtr.Zero) { Native.Destroy(_handle).ThrowIfFailed("Failed to destry media codec."); _handle = IntPtr.Zero; } _isDisposed = true; } }
private void RegisterOutputAvailableCallback() { _outputBufferAvailableCb = (packetHandle, _) => { if (_outputAvailable == null) { try { Native.Destroy(packetHandle).ThrowIfFailed("Failed to destroy packet."); } catch (Exception) { // Do not throw exception in pinvoke callback. } return; } OutputAvailableEventArgs args = null; try { args = new OutputAvailableEventArgs(packetHandle); } catch (Exception e) { try { Native.Destroy(packetHandle).ThrowIfFailed("Failed to destroy packet."); } catch { // Do not throw exception in pinvoke callback. } MultimediaLog.Error(typeof(MediaCodec).FullName, "Failed to raise OutputAvailable event", e); } if (args != null) { _outputAvailable?.Invoke(this, args); } }; Native.SetOutputBufferAvailableCb(_handle, _outputBufferAvailableCb). ThrowIfFailed("Failed to set output buffer available callback."); }
private void RegisterInputProcessed() { _inputBufferUsedCb = (lockedPacketHandle, _) => { MediaPacket packet = null; // Lock must be disposed here, note that the packet won't be disposed. using (MediaPacket.Lock packetLock = MediaPacket.Lock.FromHandle(lockedPacketHandle)) { Debug.Assert(packetLock != null); packet = packetLock.MediaPacket; } Debug.Assert(packet != null); InputProcessed?.Invoke(this, new InputProcessedEventArgs(packet)); }; Native.SetInputBufferUsedCb(_handle, _inputBufferUsedCb). ThrowIfFailed("Failed to set input buffer used callback."); }
private void ConfigureAudio(AudioMediaFormat format, bool encoder, MediaCodecTypes supportType) { int codecType = (int)format.MimeType & CodecTypeMask; if (!Enum.IsDefined(typeof(SupportedCodecType), codecType)) { throw new NotSupportedException("The format is not supported " + $"mime type : { Enum.GetName(typeof(MediaFormatAudioMimeType), format.MimeType) }"); } DoConfigure(codecType, encoder, supportType); if (encoder) { Native.SetAudioEncoderInfo(_handle, format.SampleRate, format.Channel, format.Bit, format.BitRate). ThrowIfFailed("Failed to set audio encoder information."); } else { Native.SetAudioDecoderInfo(_handle, format.SampleRate, format.Channel, format.Bit). ThrowIfFailed("Failed to set audio decoder information."); } }
private void ConfigureVideo(VideoMediaFormat format, bool encoder, MediaCodecTypes supportType) { int codecType = (int)format.MimeType & CodecTypeMask; if (!Enum.IsDefined(typeof(SupportedCodecType), codecType)) { throw new NotSupportedException("The format is not supported." + $"mime type : { Enum.GetName(typeof(MediaFormatVideoMimeType), format.MimeType) }"); } DoConfigure(codecType, encoder, supportType); if (encoder) { Native.SetVideoEncoderInfo(_handle, format.Size.Width, format.Size.Height, format.FrameRate, format.BitRate / 1000). ThrowIfFailed("Failed to set video encoder information."); } else { Native.SetVideoDecoderInfo(_handle, format.Size.Width, format.Size.Height). ThrowIfFailed("Failed to set video decoder information."); } }
/// <summary> /// Flushes both input and output buffers. /// </summary> /// <feature>http://tizen.org/feature/multimedia.media_codec</feature> /// <exception cref="NotSupportedException">The required feature is not supported.</exception> /// <since_tizen> 3 </since_tizen> public void FlushBuffers() { ValidateNotDisposed(); Native.FlushBuffers(_handle).ThrowIfFailed("Failed to flush buffers."); }
private void RegisterEosReached() { _eosCb = _ => EosReached?.Invoke(this, EventArgs.Empty); Native.SetEosCb(_handle, _eosCb).ThrowIfFailed("Failed to set eos callback."); }
/// <summary> /// Unprepares the MediaCodec. /// </summary> /// <feature>http://tizen.org/feature/multimedia.media_codec</feature> /// <exception cref="NotSupportedException">The required feature is not supported.</exception> /// <since_tizen> 3 </since_tizen> public void Unprepare() { ValidateNotDisposed(); Native.Unprepare(_handle).ThrowIfFailed("Failed to unprepare media codec."); }
private void UnregisterOutputAvailableCallback() { Native.UnsetOutputBufferAvailableCb(_handle).ThrowIfFailed("Failed to unregister output available callback."); }