FFmpeg at c++ "Freeze" problems

For the developers that use FFmpeg in their software.
Post Reply
kiwi
Posts: 1
Joined: Tue Mar 20, 2018 8:51 am

FFmpeg at c++ "Freeze" problems

Post by kiwi » Tue Mar 20, 2018 9:10 am

hello,

I used FFmpeg for get a stream by a camera (Bosch autodome 4000) , and I have 2 problems, the first is my stream have some " freeze" , Second problems is that the colors of the image are not good.
Capture.PNG
I program at c/c++ :

Code: Select all

CMFCApplication1Dlg *pDlg = (CMFCApplication1Dlg *)carg;
	int64_t timeBase;

	char src_filename[180];
	int refcount = 0;
	int video_stream_idx = -1;
	int audio_stream_idx = -1;
	AVCodecContext *video_dec_ctx = NULL;
	AVStream *video_stream = NULL;
	AVFormatContext *fmt_ctx = NULL;
	int ret;

	strcpy_s(src_filename, 180, "rtsp://service:CyresCenco1*@172.26.48.202/rtsp_tunnel");
	//strcpy_s(src_filename, 180, "c:\\temp\\Test.avi");

	/* open input file, and allocate format context */
	//int ret = avformat_open_input(&fmt_ctx, "c:\\temp\\Test.avi", NULL, NULL);
	ret = avformat_open_input(&fmt_ctx, src_filename, NULL, NULL);
	if (ret < 0)
	{
		return -1;
	}

	ret = avformat_find_stream_info(fmt_ctx, NULL);
	if (ret < 0)
	{
		return -1;
	}

	int stream_index;
	AVStream *st;
	AVCodec *dec = NULL;
	AVDictionary *opts = NULL;

	ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
	if (ret < 0)
	{
		return -1;
	}
	else
	{
		stream_index = ret;
		st = fmt_ctx->streams[stream_index];

		/* find decoder for the stream */
		dec = avcodec_find_decoder(st->codecpar->codec_id);
		if (!dec)
		{
			return -1;
		}

		/* Allocate a codec context for the decoder */
		video_dec_ctx = avcodec_alloc_context3(dec);
		if (!video_dec_ctx)
		{
			return -1;
		}

		/* Copy codec parameters from input stream to output codec context */
		if ((ret = avcodec_parameters_to_context(video_dec_ctx, st->codecpar)) < 0)
		{
			fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
				av_get_media_type_string(AVMEDIA_TYPE_VIDEO));
			return -1;
		}

		/* Init the decoders, with or without reference counting */
		av_dict_set(&opts, "refcounted_frames", refcount ? "1" : "0", 0);
		if ((ret = avcodec_open2(video_dec_ctx, dec, &opts)) < 0)
		{
			return -1;
		}
		video_stream_idx = stream_index;
	}

	video_stream = fmt_ctx->streams[video_stream_idx];

	/*FILE *video_dst_file = fopen("d:\\temp\\ocack.avi", "wb");
	if (!video_dst_file)
	{
		return -1;
	}*/

	/* allocate image where the decoded image will be put */
	int width_src, height_src;
	enum AVPixelFormat pix_fmt_src, pix_fmt_dst;

	uint8_t *video_tmp_data[4] = { NULL };
	int      video_tmp_linesize[4];

	uint8_t *video_dst_data[4] = { NULL };
	int      video_dst_linesize[4];
	width_src = video_dec_ctx->width;
	height_src = video_dec_ctx->height;
	pix_fmt_src = video_dec_ctx->pix_fmt;
	pix_fmt_dst = AV_PIX_FMT_RGB24;

	//AfxMessageBox(av_get_pix_fmt_name(pix_fmt_dst));

	ret = av_image_alloc(video_tmp_data, video_tmp_linesize,
		width_src, height_src, pix_fmt_src, 1); 
	
	ret = av_image_alloc(video_dst_data, video_dst_linesize,
		width_src, height_src, pix_fmt_dst /* pix_fmt_src */, 1);
	if (ret < 0)
	{
		return -1;
	}
	int video_dst_bufsize = ret;

	av_dump_format(fmt_ctx, 0, src_filename, 0);

	if (!video_stream)
	{
		return -1;
	}

	AVFrame *frame;
	frame = av_frame_alloc();
	if (!frame)
	{
		return -1;
	}

	/* initialize packet, set data to NULL, let the demuxer fill it */
	AVPacket pkt;
	av_init_packet(&pkt);
	pkt.data = NULL;
	pkt.size = 0;

	int got_frame;

	int width_dst = width_src / 3;
	int height_dst = height_src / 3;

	SwsContext *img_convert_ctx = sws_getContext(width_src, height_src, pix_fmt_src, width_dst, height_dst, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

	CDC *pDC = pDlg->GetDC();
	HDC hDC = *pDC;
	HDC hDCMem = CreateCompatibleDC(hDC);

	BYTE* pbmpData = NULL;

	BITMAPINFO bmi = { 0 };
	bmi.bmiHeader.biBitCount = 24;
	bmi.bmiHeader.biCompression = BI_RGB;
	bmi.bmiHeader.biHeight = -height_src;
	bmi.bmiHeader.biWidth = width_src;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biSizeImage = height_src * width_src * 3;
	hbmp = CreateDIBSection(hDCMem, &bmi, DIB_RGB_COLORS, (LPVOID *)&pbmpData, NULL, 0);


	timeBase = (int64_t(video_dec_ctx->time_base.num) * AV_TIME_BASE) / int64_t(video_dec_ctx->time_base.den);

	int cmpFrame = 1;
	int64_t seekTarget = int64_t(cmpFrame) * timeBase;


	/* read frames from the file */
	while (av_read_frame(fmt_ctx, &pkt) >= 0)
	{
		cmpFrame = cmpFrame + 5;
		seekTarget = int64_t(cmpFrame) * timeBase;
		AVPacket orig_pkt = pkt;
		do
		{
			got_frame = 0;
			ret = avcodec_decode_video2(video_dec_ctx, frame, &got_frame, &pkt);
			if (ret < 0)
			{
				return -1;
			}
			if (got_frame)
			{
				if (frame->width != width_src || frame->height != height_src ||
					frame->format != pix_fmt_src)
				{
					return -1;
				}
			}

			av_image_copy(video_tmp_data, video_tmp_linesize,
			(const uint8_t **)(frame->data), frame->linesize,
			pix_fmt_src, width_src, height_src);

			sws_scale(img_convert_ctx, video_tmp_data, video_tmp_linesize, 0, height_src, video_dst_data, video_dst_linesize);

			EnterCriticalSection(&csBitMap);
			video_dst_data[0] = (uint8_t*)pbmpData;
			video_dst_linesize[0] = width_src * 3;
			SelectObject(hDCMem, hbmp);
			BitBlt(hDC, 0, 0, width_src, height_src, hDCMem, 0, 0, SRCCOPY);
			//pDlg->m_BMP.SetBitmap(hbmp);
			LeaveCriticalSection(&csBitMap);

			//fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);

			if (ret < 0)
				break;
			pkt.data += ret;
			pkt.size -= ret;
		} while (pkt.size > 0);
		av_packet_unref(&orig_pkt);
	}

	char Output[200];
	sprintf(Output, "Play the output video file with the command:\n"
		"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d\n",
		av_get_pix_fmt_name(pix_fmt_src), width_src, height_src);



PS : I'm sorry by my English levels :(

Post Reply
'