<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi,<div><br></div><div>I have three problems. </div><div><br></div><div>First problem is that when I transcode Video and Audio the audio is a second behind the video. I think the problem is that the video stream is not delayed as the audio. I've run ffplay with video/audio and I can see that the video and audio is delayed about a second, but when running from code the video is not delayed at all (I have SDL preview) its instant. Maybe that's one of the reasons they are out of sync. </div><div><br></div><div>Second problem is that when running same code with same video, if the camera is recording in low light, the resulting file is 'fast-forwarded'. E.g. if I record 12 sec video, the resulting file is indeed 12 secs, but the frames recorded fit in 7 secs, playing fast and after the 7 second the video freezes. </div><div><br></div><div>Third problem, which is not so bad, but it is a problem. There is config option where if the user wants specific resolution to record with it. Of course using `dshow` I'm check if the resolution is supported from the input device first. With some cameras, setting 'video_size' even when supported the decoder fails. </div><div><br></div><div>Now some code:</div><div>Creating the Input format context</div><div><div>private AVFormatContext* CreateFormatContext()</div><div>        {</div><div>            AVDictionary* options = null;</div><div><br></div><div>            ffmpeg.av_dict_set(&options, "packet-buffering", "0", 0);</div><div>            ffmpeg.av_dict_set(&options, "sync", "1", 0);</div><div>            ffmpeg.av_dict_set(&options, "rtsp_transport", "tcp", 0);</div><div>            ffmpeg.av_dict_set(&options, "reconnect", "1", 0);</div><div>            //ffmpeg.av_dict_set(&options, "analyzeduration", "2000000", 0);</div><div>            //ffmpeg.av_dict_set(&options, "probesize", (16384 * 16).ToString(), 0);</div><div>            ffmpeg.av_dict_set(&options, "max_delay", "0", 0);</div><div>            ffmpeg.av_dict_set(&options, "reorder_queue_size", "0", 0);</div><div>            ffmpeg.av_dict_set(&options, "skip_frame", "8", 0);</div><div>            ffmpeg.av_dict_set(&options, "skip_loop_filter", "48", 0);</div><div>            ffmpeg.av_dict_set(&options, "rtbufsize", "1500M", 0);</div><div><br></div><div>            if (!string.IsNullOrEmpty(_resolution))</div><div>            {</div><div>                var resolution = DShow.GetConfiguredCameraResolution(_streamUrl, _resolution);</div><div>                if (resolution != null)</div><div>                {</div><div>                    ffmpeg.av_dict_set(&options, "video_size", resolution.Resolution, 0);</div><div>                    //ffmpeg.av_dict_set(&options, "r", resolution.FrameRate.ToString(), 0);</div><div>                }</div><div>                else</div><div>                {</div><div>                }</div><div>            }</div><div>            AVFormatContext* pInputFmtCtx = ffmpeg.avformat_alloc_context();</div><div><br></div><div>            AVInputFormat* inputFormat = null;</div><div><br></div><div>            if (!string.IsNullOrEmpty(_format))</div><div>            {</div><div>                inputFormat = ffmpeg.av_find_input_format(_format);</div><div><br></div><div>                if (inputFormat == null)</div><div>                {</div><div>                    </div><div>                }</div><div>            }</div><div><br></div><div>            int ret = ffmpeg.avformat_open_input(&pInputFmtCtx, _streamUrl, inputFormat, &options);</div><div><br></div><div>            if (ret != 0)</div><div>            {</div><div>                </div><div>            }</div><div><br></div><div>            return pInputFmtCtx;</div><div>        }</div></div><div><br></div><div>Creating the decoder</div><div><div>AVStream* videoStream = InputFormatContext->streams[VideoStreamIndex];</div><div>            AVCodecParameters* videoCodecParams = videoStream->codecpar;</div><div>            AVCodec* videoDecoder = ffmpeg.avcodec_find_decoder(videoCodecParams->codec_id);</div><div><br></div><div>            VideoDecodeContext = ffmpeg.avcodec_alloc_context3(videoDecoder);</div><div><br></div><div>            if (ffmpeg.avcodec_parameters_to_context(VideoDecodeContext, videoCodecParams) < 0)</div><div>            {</div><div>            }</div><div><br></div><div>            if (ffmpeg.avcodec_open2(VideoDecodeContext, videoDecoder, null) < 0)</div><div>            {</div><div>            }</div></div><div><br></div><div>Creating the OutputFormatContext</div><div><div>private AVFormatContext* CreateOutputContext()</div><div>        {</div><div>            //open the output context</div><div>            AVFormatContext* pOutputFmtCtx = null;</div><div><br></div><div>            if (ffmpeg.avformat_alloc_output_context2(&pOutputFmtCtx, null, null, _fileName) != 0)</div><div>            {</div><div>            }</div><div><br></div><div>            return pOutputFmtCtx;</div><div>        }</div></div><div><br></div><div>Creating H264 decoder</div><div><div>private void CreateH264Encoder(AVStream* inputStream, AVStream* outputStream)</div><div>        {</div><div>            AVRational framerate = ffmpeg.av_guess_frame_rate(_inputContext.InputFormatContext, inputStream, null);</div><div><br></div><div>            var key = Registry.LocalMachine.OpenSubKey(@"HARDWARE\DESCRIPTION\System\CentralProcessor\0\");</div><div>            var processorName = key.GetValue("ProcessorNameString");</div><div><br></div><div>            AVCodec* videoEncoder;</div><div><br></div><div>            if (processorName.ToString().IndexOf("AMD", StringComparison.InvariantCultureIgnoreCase) != -1)</div><div>            {</div><div>                videoEncoder = ffmpeg.avcodec_find_encoder_by_name("libx264");</div><div>                PixelFormat = AVPixelFormat.AV_PIX_FMT_YUV420P;</div><div>            } else</div><div>            {</div><div>                videoEncoder = ffmpeg.avcodec_find_encoder_by_name("h264_qsv");</div><div>                if (videoEncoder == null)</div><div>                {</div><div>                    videoEncoder = ffmpeg.avcodec_find_encoder_by_name("libx264");</div><div>                    PixelFormat = AVPixelFormat.AV_PIX_FMT_YUV420P;</div><div>                }</div><div>            }</div><div><br></div><div>            if (videoEncoder == null)</div><div>            {</div><div>                </div><div>            }</div><div><br></div><div>            VideoEncodeContext = ffmpeg.avcodec_alloc_context3(videoEncoder);</div><div><br></div><div>            if (VideoEncodeContext == null)</div><div>            {</div><div>                </div><div>            }</div><div><br></div><div>            VideoEncodeContext->width = _inputContext.VideoDecodeContext->width;</div><div>            VideoEncodeContext->height = _inputContext.VideoDecodeContext->height;</div><div>            VideoEncodeContext->pix_fmt = PixelFormat;</div><div>            VideoEncodeContext->bit_rate = H264_ENCODER_BIT_RATE;</div><div>            VideoEncodeContext->rc_buffer_size = H264_ENCODER_BUFFER_SIZE;</div><div>            VideoEncodeContext->rc_max_rate = H264_ENCODER_MAX_RATE;</div><div>            VideoEncodeContext->rc_min_rate = H264_ENCODER_MIN_RATE;</div><div>            VideoEncodeContext->framerate = framerate;</div><div>            VideoEncodeContext->max_b_frames = 0;</div><div>            VideoEncodeContext->time_base = ffmpeg.av_inv_q(framerate);</div><div>            VideoEncodeContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;</div><div><br></div><div>            ffmpeg.av_opt_set(VideoEncodeContext->priv_data, "preset", "slow", 0);</div><div>            ffmpeg.av_opt_set(VideoEncodeContext->priv_data, "vprofile", "baseline", 0);</div><div><br></div><div>            if (ffmpeg.avcodec_open2(VideoEncodeContext, videoEncoder, null) < 0)</div><div>            {</div><div>                </div><div>            }</div><div><br></div><div>            ffmpeg.avcodec_parameters_from_context(outputStream->codecpar, VideoEncodeContext);</div><div>        }</div></div><div><br></div><div>Decoding/Encoding is the same as the latest api examples so I'll skip it. </div><div>Writing the frame to the file</div><div><br></div><div><div>AVStream* out_stream = _outputContext.OutputFormatContext->streams[out_stream_index];</div><div><br></div><div>                ffmpeg.av_packet_rescale_ts(avPacketPtr, ctx->time_base, out_stream->time_base);</div><div><br></div><div>                ret = ffmpeg.av_interleaved_write_frame(_outputContext.OutputFormatContext, avPacketPtr);</div></div></div></div></div></div></div></div>