Beispiel #1
0
        /// <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();
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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.");
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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.");
        }
Beispiel #7
0
        /// <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.");;
        }
Beispiel #8
0
        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.");
        }
Beispiel #9
0
        /// <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;
            }
        }
Beispiel #10
0
        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.");
        }
Beispiel #11
0
        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.");
        }
Beispiel #12
0
        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.");
            }
        }
Beispiel #13
0
        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.");
            }
        }
Beispiel #14
0
        /// <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.");
        }
Beispiel #15
0
        private void RegisterEosReached()
        {
            _eosCb = _ => EosReached?.Invoke(this, EventArgs.Empty);

            Native.SetEosCb(_handle, _eosCb).ThrowIfFailed("Failed to set eos callback.");
        }
Beispiel #16
0
        /// <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.");
        }
Beispiel #17
0
 private void UnregisterOutputAvailableCallback()
 {
     Native.UnsetOutputBufferAvailableCb(_handle).ThrowIfFailed("Failed to unregister output available callback.");
 }