librtmp库在RTMP_Read阻塞,做成多线程时不方便,可以改成非阻塞:
跟踪代码,在
- RTMP_Read-->Read_1_Packet-->RTMP_GetNextMediaPacket里:
-
-
- while (!bHasMediaPacket && RTMP_IsConnected(r)
- && RTMP_ReadPacket(r, packet))
- {
- ...
- bHasMediaPacket = RTMP_ClientPacket(r, packet);
-
-
- if (!bHasMediaPacket)
- {
- RTMPPacket_Free(packet);
- }
- ...
- }
当没有收到数据时,相当于执行while(1),没有检测主动断开的事件。如果一直没有来数据,socket也不断,这就是个死循环了。rtmpdump是基于命令行的,可以直接ctrl-c退出了事,如果自己写一个重复的多路服务,这样不行,需要做非阻塞处理。
方法:
增加一个回调,检测是否需要中断:
在rtmp.h里增加一个结构体:
- typedef struct AVIOInterruptCB {
- int (*callback)(void*);
- void *opaque;
- } AVIOInterruptCB;
在RTMP里增加一个变量:
- AVIOInterruptCB interrupt_callback;
RTMP_Init的时候:
- r->interrupt_callback.opaque = NULL;
- r->interrupt_callback.callback = NULL;
在外面使用的时候,先定义一个函数:
- static int decode_interrupt_cb(void *ctx)
- {
- MYClass *is = (MYClass *)ctx;
- return is->abort_request;
- }
RTMP初始化:
- r->interrupt_callback.callback = decode_interrupt_cb;
- r->interrupt_callback.opaque = this;
为了省事,回调方法从ffplay里拿来的。
(sxcong) |