private void Clear() { format_context = null; p_avformat_context = IntPtr.Zero; p_video_codec = IntPtr.Zero; p_audio_codec = IntPtr.Zero; video_stream_index = -1; audio_stream_index = -1; video_codec_context = null; audio_codec_context = null; video_stream = null; audio_stream = null; p_frame = IntPtr.Zero; p_frame_rgb = IntPtr.Zero; p_packet = IntPtr.Zero; if (p_audio_buffer != IntPtr.Zero) { Marshal.FreeHGlobal(p_audio_buffer); p_audio_buffer = IntPtr.Zero; } video_buffer_manager_ = null; audio_buffer_manager_ = null; video_rate_ = 24; video_scale_ = 1; key_frame_list_ = new List <int>(); key_dts_list_ = new List <long>(); current_frame_ = 0; last_requested_frame_ = 0; audio_priority_times_ = 0; av_packet_queue_ = new Queue <PacketContainer>(); thread_end_event_ = new ManualResetEvent(true); command_queue_ = new List <Command>(); fixed_video_width_ = -1; fixed_video_height_ = -1; }
/// <summary> /// 動画ファイルを開く /// </summary> /// <param name="filename">ファイルパス</param> /// <param name="width">動画サイズを固定する場合の幅(負の値を指定した場合は元の動画サイズになる)</param> /// <param name="height">動画サイズを固定する場合の高さ(負の値を指定した場合は元の動画サイズになる)</param> /// <param name="memory_size">使用するメモリサイズ(MB)(負の値を指定した場合は自動設定)</param> public void Open(string filename, int video_width, int video_height, int memory_size) { OpenCodec(filename); fixed_video_width_ = video_width; fixed_video_height_ = video_height; video_rate_ = video_stream.r_frame_rate.num; video_scale_ = video_stream.r_frame_rate.den; p_frame = AVCodecAPI.avcodec_alloc_frame(); p_frame_rgb = AVCodecAPI.avcodec_alloc_frame(); p_packet = AVCodecAPI.av_malloc(Marshal.SizeOf(new AVPacket())); long last_dts = 0; int c = 0; bool is_first = true; int start_frame = 0; while (c >= 0) { if (!is_first) { AVCodecAPI.av_seek_frame(p_avformat_context, video_stream_index, last_dts + 1, 0); } while ((c = AVCodecAPI.av_read_frame(p_avformat_context, p_packet)) >= 0) { PacketContainer container = new PacketContainer(p_packet); if (container.packet.stream_index == video_stream_index) { last_dts = container.packet.dts; key_dts_list_.Add(last_dts); key_frame_list_.Add(DtsToVideoFrame(last_dts)); if (is_first) { is_first = false; start_frame = key_frame_list_[key_frame_list_.Count - 1]; } break; } container.Destruct(); } } AVCodecAPI.av_seek_frame(p_avformat_context, video_stream_index, 0, 0); if (IsTimeScaleFour()) { video_scale_ *= 4; for (int i = 0; i < key_frame_list_.Count; ++i) { key_frame_list_[i] /= 4; } } if (video_rate_ / video_scale_ > 60) { FixIllegalFrameRate(); } if (HasVideo) { if (memory_size <= 0) { memory_size = Math.Min(Math.Max(BufferContainer.GetMemorySize() / (1024 * 1024) - 500, 100), 500); // 最小100MB、最大500MB } video_buffer_manager_ = new VideoBufferManager(this, FrameLength, memory_size * 1024 * 1024 / VideoPictureBufferSize, start_frame); } if (HasAudio) { audio_buffer_manager_ = new AudioBufferManager(); audio_buffer_manager_.SetDataLength(AudioSampleRate * AudioChannel * AudioBytesPerSample * format_context.duration / 1000000); p_audio_buffer = Marshal.AllocHGlobal(audio_temp_buffer_size_); audio_priority_times_ = 10; } StartDecoding(); }