多线程SDL_DestroyWindow阻塞问题
来源:互联网 发布:linux中的dd命令 编辑:程序博客网 时间:2024/06/05 18:12
来源:http://bbs.csdn.net/topics/392273728
运用多线程实现播放器,用ffmpeg解码sdl显示,在停止播放销毁窗体SDL_DestroyWindow时发生阻塞。
以下是部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//SDL线程
int
sfp_refresh_thread(
void
*opaque)
{
while
(thread_exit==0)
{
SDL_Event event;
event.type = SFM_REFRESH_EVENT;
SDL_PushEvent(&event);
}
//Quit
SDL_Event event;
event.type = SFM_BREAK_EVENT;
SDL_PushEvent(&event);
return
0;
}
//视频播放函数
int
simplest_ffmpeg_player(
LPVOID
lpParam)
{
int
i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame,*pFrameYUV;
uint8_t *out_buffer;
AVPacket packet;
int
ret, got_picture;
//------------SDL----------------
int
screen_w,screen_h;
SDL_Window *screen;
SDL_Renderer* sdlRenderer;
SDL_Texture* sdlTexture;
SDL_Rect sdlRect;
SDL_Thread *video_tid;
SDL_Event event;
struct
SwsContext *img_convert_ctx;
CRTSPPlayerDlg *dlg=(CRTSPPlayerDlg *)lpParam;
static
AVInputFormat *file_iformat;
AVFormatContext *ic = NULL;
AVDictionary **opts;
AVDictionaryEntry *t;
av_register_all();
avformat_network_init();
AVCodec *pACodec = avcodec_find_decoder(AV_CODEC_ID_H264);
pCodecCtx = NULL;
pCodecCtx = avcodec_alloc_context3(pACodec);
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
pCodecCtx->width = 1920;
pCodecCtx->height = 1080;
if
(avcodec_open2(pCodecCtx, pACodec, NULL) < 0)
{
AfxMessageBox(
"Could not open codec.\n"
);
return
-1;
}
pFrame=av_frame_alloc();
pFrameYUV=av_frame_alloc();
out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
if
(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER))
{
AfxMessageBox(
"Could not initialize SDL\n"
);
return
-1;
}
//SDL 2.0 Support for multiple windows
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
//===========================================
//显示在MFC控件上
screen = SDL_CreateWindowFrom(dlg->GetDlgItem(IDC_SCREEN)->GetSafeHwnd());
//===========================================
if
(!screen)
{
AfxMessageBox(
"SDL: could not create window - exiting\n"
);
return
-1;
}
sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
//IYUV: Y + U + V (3 planes)
//YV12: Y + V + U (3 planes)
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);
sdlRect.x=0;
sdlRect.y=0;
sdlRect.w=screen_w;
sdlRect.h=screen_h;
video_tid = SDL_CreateThread(sfp_refresh_thread,NULL,NULL);
//------------SDL End------------
//Event Loop
av_init_packet(&packet);
char
dateBuf[DUMMY_SINK_RECEIVE_BUFFER_SIZE] =
""
;
for
(;;)
{
//Wait
SDL_WaitEvent(&event);
if
(event.type==SFM_REFRESH_EVENT)
{
//------------------------------
memset
(dateBuf, 0,
sizeof
(dateBuf));
int
len = dlg->read(dateBuf, 1);
if
(len == 0)
{
if
(thread_exit == 1)
{
break
;
}
Sleep(20);
continue
;
}
packet.data = (uint8_t *)dateBuf;
packet.size = len;
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
if
(ret < 0)
{
continue
;
AfxMessageBox(
"Decode Error.\n"
);
return
-1;
}
if
(got_picture)
{
sws_scale(img_convert_ctx, (
const
uint8_t*
const
*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, NULL);
SDL_RenderPresent( sdlRenderer );
}
av_free_packet(&packet);
}
else
if
(event.type==SDL_QUIT)
{
thread_exit=1;
}
else
if
(event.type==SFM_BREAK_EVENT)
{
break
;
}
}
sws_freeContext(img_convert_ctx);
SDL_DestroyWindow(screen);
//此函数会阻塞
SDL_DestroyRenderer(sdlRenderer);
SDL_DestroyTexture(sdlTexture);
SDL_Quit();
//此函数会阻塞
dlg->GetDlgItem(IDC_SCREEN)->ShowWindow(SW_SHOWNORMAL);
av_free(out_buffer);
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
return
0;
}
//播放线程
UINT
Thread_Play(
LPVOID
lpParam){
simplest_ffmpeg_player(lpParam);
return
0;
}
//开启播放
void
CRTSPPlayerDlg::OnBnClickedButtonPlay()
{
// TODO: 在此添加控件通知处理程序代码
m_ThreadHandleRetVal = CreateThread(NULL, 0, LPTHREAD_START_ROUTINE)Thread_Play,
this
, 0, NULL);
}
//停止播放
void
CRTSPPlayerDlg::OnBnClickedButtonStop()
{
// TODO: 在此添加控件通知处理程序代码
thread_exit = 1;
m_pRtsp->stopRTSPClient();
WaitForSingleObject(m_ThreadHandleRetVal, INFINITE);
//等待播放线程结束
.
.
.
.
}
楼主,这个问题是否解决了?
我也遇到了这个问题,我的代码和你的非常接近,单步跟踪看,是阻塞在ShowWindow(hwnd, SW_HIDE);这里了。不知道啥原因,郁闷了很多天了。
如果解决了,望楼主赐教!
我也是这个问题 SDL_DestroyWindow阻塞。不知道什么原因。
但是 SDL_Window *screen; 定义为全局变量,然后将 SDL_DestroyWindow(screen);放到停止按钮里面销毁线程前就没问题。纠结中
阅读全文
0 0
- 多线程SDL_DestroyWindow阻塞问题
- 多线程 sleep usleep 阻塞问题
- CMD IO 阻塞问题 (多线程) 解决
- 多线程阻塞问题的监控与调试
- iOS解决多线程 线程阻塞问题
- Python中多线程的阻塞问题
- 关于gethostbyname在多线程环境下的阻塞问题
- 多线程工作环境下MQ get操作的阻塞问题
- 关于gethostbyname在多线程环境下的阻塞问题
- 在多线程中,recv非阻塞模式带来的问题
- [转]关于gethostbyname在多线程环境下的阻塞问题
- 关于gethostbyname在多线程环境下的阻塞问题
- 关于gethostbyname在多线程环境下的阻塞问题
- 关于gethostbyname在多线程环境下的阻塞问题
- java socket多线程通讯,解决read阻塞问题
- java多线程-阻塞队列
- Java多线程 -- 阻塞队列
- Java多线程 -- 阻塞栈
- python简单的文件读写操作
- SpringMVC 导出Excel案例
- java查询数据导出excel并返回给浏览器下载
- MySQL 字符集
- tftp如何使用?
- 多线程SDL_DestroyWindow阻塞问题
- 漫谈c语言历史
- Qt的XML封装类QXmlWrapper,实现XML文件的创建、删除以及元素节点的增加、删除、修改与查找等。
- AngularJs 技术实现简单的表格管理
- ol2加载ArcGis发布的wfs
- css 图片自适应
- oracle的几种循环示例
- ios android 真机调试
- 图像处理 椒盐噪声