ffmpeg4教程工具方法

//win32显示
static void Show(HWND hwnd, unsigned char* rgb, int w, int h, bool fill)
{
	HDC hdc = GetDC(hwnd);//获取当前的显示设备上下文

	RECT rect;
	GetClientRect(hwnd, &rect);
	int cxClient = rect.right;
	int cyClient = rect.bottom;

	if (cxClient <= 0 || cyClient <= 0) {
		return;
	}

	HDC  hdcsource = CreateCompatibleDC(NULL);//创建存放图象的显示缓冲
	HBITMAP bitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);

	SelectObject(hdcsource, bitmap);    //将位图资源装入显示缓冲

	SetStretchBltMode(hdcsource, COLORONCOLOR);

	BITMAPINFO  bmi;
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = w;
	bmi.bmiHeader.biHeight = -h;
	bmi.bmiHeader.biCompression = BI_RGB;
	bmi.bmiHeader.biBitCount = 24;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biClrUsed = 0;
	bmi.bmiHeader.biClrImportant = 0;
	bmi.bmiHeader.biSizeImage = 0;


	if (!fill) {

		int des_x = 0;
		int des_y = 0;
		int des_w = 0;
		int des_h = 0;


		if (1.0*cxClient / cyClient > 1.0*w / h) {
			des_h = cyClient;
			des_w = des_h * w / h;
			des_x = (cxClient - des_w) / 2;
			des_y = 0;
		}
		else {
			des_w = cxClient;
			des_h = des_w * h / w;
			des_x = 0;
			des_y = (cyClient - des_h) / 2;
		}


		BitBlt(hdcsource, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY);
		StretchDIBits(hdcsource, des_x, des_y, des_w, des_h, \
			0, 0, w, h, rgb, &bmi, DIB_RGB_COLORS, SRCCOPY);
		BitBlt(hdc, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY);
	}
	else {
		StretchDIBits(hdcsource, 0, 0, rect.right - rect.left, rect.bottom - rect.top, \
			0, 0, w, h, rgb, &bmi, DIB_RGB_COLORS, SRCCOPY);

		BitBlt(hdc, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY);//将图象显示缓冲的内容直接显示到屏幕
	}

	DeleteObject(bitmap);
	DeleteDC(hdcsource);
	ReleaseDC(hwnd, hdc);
}
static LRESULT CALLBACK WinProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{

	switch (umsg)
	{
	case WM_KEYDOWN:
	{
		if (wparam == VK_SPACE) {

		}
	}
	break;
	case WM_LBUTTONDOWN:
	{

	}
	break;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, umsg, wparam, lparam);
}
static char *dup_wchar_to_utf8(wchar_t *w)
{
    char *s = NULL;
    int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
    s = (char *)av_malloc(l);
    if (s)
        WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
    return s;
}

//

static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{

	/* rescale output packet timestamp values from codec to stream timebase */
	av_packet_rescale_ts(pkt, *time_base, st->time_base);
	pkt->stream_index = st->index;

	/* Write the compressed frame to the media file. */
	av_interleaved_write_frame(fmt_ctx, NULL);
	//log_packet(fmt_ctx, pkt);
	return av_interleaved_write_frame(fmt_ctx, pkt);
}

声音avframe创建

static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int chnls, int sample_rate, int nb_samples)
{
	AVFrame *frame = av_frame_alloc();
	int ret;

	if (!frame) {
		fprintf(stderr, "Error allocating an audio frame\n");
		return NULL;
	}

	frame->format = sample_fmt;
	frame->channel_layout = channel_layout;
	frame->channels = chnls;
	frame->sample_rate = sample_rate;
	frame->nb_samples = nb_samples;

	if (nb_samples) {
		ret = av_frame_get_buffer(frame, 1);
		if (ret < 0) {
			fprintf(stderr, "Error allocating an audio buffer\n");
			return NULL;
		}
	}

	return frame;
}

//图片avframe创建


static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
	AVFrame *picture;
	int ret;

	picture = av_frame_alloc();
	if (!picture)
		return NULL;

	picture->format = pix_fmt;
	picture->width = width;
	picture->height = height;

	/* allocate the buffers for the frame data */
	ret = av_frame_get_buffer(picture, 4);
	if (ret < 0) {
		fprintf(stderr, "Could not allocate frame data.\n");
		return NULL;
	}

	return picture;
}

//链表队列

static int initFrameList(FrameList **pFrameList, int max) {
	int ret = 0;
	FrameList* p = NULL;
	*pFrameList = (FrameList*)av_mallocz(sizeof(FrameList));
	p = *pFrameList;
	if (p == NULL) return -1;
	ret = pthread_mutex_init(&p->mutex, NULL);
	if (ret != 0) {
		av_freep(p);
		return -1;
	}
	ret = pthread_cond_init(&p->cond, NULL);
	if (ret != 0) {
		av_freep(&p);
		return -1;
	}
	ret = pthread_cond_init(&p->wait, NULL);
	if (ret != 0) {
		av_freep(&p);
		return -1;
	}

	p->max = max;
	return 0;
}

static int pushFrame(FrameList *p, AVFrame *avframe, int64_t pts) {
	int ret = 0;
	Frame *frm = NULL;
	if (p == NULL || p->exit) { return 0; }

	pthread_mutex_lock(&p->mutex);
	while (!p->exit && p->frmSize > p->max) {
		pthread_cond_wait(&p->wait, &p->mutex);
	}
	if (p->exit) {
		pthread_mutex_unlock(&p->mutex);
		return 0;
	}
	frm = (Frame*)av_mallocz(sizeof(Frame));
	if (frm) {
		frm->pts = pts;
		frm->avframe = alloc_picture((AVPixelFormat)avframe->format, avframe->width, avframe->height);
		av_frame_copy(frm->avframe, avframe);
		if (p->end == NULL) {
			p->frame = frm;
		}
		else {
			p->end->next = frm;
		}
		p->end = frm;
		p->frmSize++;
		ret = 1;
		pthread_cond_signal(&p->cond);
	}

	pthread_mutex_unlock(&p->mutex);

	return ret;
}

static int64_t popFrame(FrameList *p, AVFrame **avframe) {
	int64_t ret = 0;
	if (p == NULL || p->exit) return 0;
	pthread_mutex_lock(&p->mutex);
	while (!p->exit && p->frmSize < 1) {
		pthread_cond_wait(&p->cond, &p->mutex);
	}

	if (p->exit) {
		pthread_mutex_unlock(&p->mutex);
		return -1;
	}

	if (p->frame == p->end) {
		ret = p->frame->pts;
		*avframe = alloc_picture((AVPixelFormat)p->frame->avframe->format, p->frame->avframe->width, p->frame->avframe->height);
		av_frame_copy(*avframe, p->frame->avframe);
		av_frame_free(&p->frame->avframe);
		av_freep(&p->frame);
		p->frame = NULL;
		p->end = NULL;

	}
	else {
		Frame *temp = p->frame;
		p->frame = temp->next;
		ret = temp->pts;
		if (temp->avframe != NULL) {
			*avframe = alloc_picture((AVPixelFormat)temp->avframe->format, temp->avframe->width, temp->avframe->height);
			av_frame_copy(*avframe, temp->avframe);
			av_frame_free(&temp->avframe);
		}
		av_freep(&temp);
	}
	p->frmSize--;
	pthread_cond_signal(&p->wait);
	pthread_mutex_unlock(&p->mutex);
	return ret;
}
static void destoryFrameList(FrameList *pFrameList) {
	if (pFrameList == NULL) return;
	{
		Frame *frm = NULL;
		FrameList *p = pFrameList;
		pthread_mutex_lock(&p->mutex);
		p->exit = 1;

		frm = p->frame;
		while (frm) {
			Frame *temp = frm->next;
			if (temp != NULL) {

				av_frame_unref(temp->avframe);
			}
			frm = temp;
		}
		pthread_mutex_unlock(&p->mutex);
	}

}

static void clearFrameList(FrameList *pFrameList) {
	if (pFrameList == NULL) return;
	{
		Frame *frm = NULL;
		FrameList *p = pFrameList;

		if (p->frmSize < 1) {
			return;
		}

		pthread_mutex_lock(&p->mutex);

		frm = p->frame;
		while (frm) {
			Frame *temp = frm->next;
			if (temp != NULL) {
				av_frame_free(&temp->avframe);
			}

			frm = temp;
		}
		p->frmSize = 0;
		pthread_mutex_unlock(&p->mutex);
	}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值