[FFmpeg-devel] dshow hang when device is unplugged
Don Moir
donmoir at comcast.net
Wed Nov 28 01:24:45 CET 2012
dshow.c doesn't do any event handling. So if a device is unplugged it will hang in dshow_read_packet since the ctx->event will never be signaled.
As far as I know, event handling is the only way to catch an unplugged device that was plugged in.
See WaitForSingleObject (ctx->event,INFINITE) in dshow_read_packet.
This makes avdevice unusable for me so I looked into fixing it. A thread will be left hanging and app won't be able to close. I could close the thread but that doesn't solve the problem.
I took the least elegant but quickest way to fix it.
To struct dshow_ctx I added IMediaEvent *media_event;
Then in dshow_read_header I added:
IMediaEvent *media_event = NULL;
// right after IID_ImediaControl is retreived I added:
r = IGraphBuilder_QueryInterface (graph,IID_IMediaEvent,(void **),&media_event);
if (r != S_OK) {
av_log(avctx,AV_LOG_ERROR,"Could not get media event.\n");
goto error;
}
ctx->media_event = media_event.
Also added a release for media_event on close.
So now back to dshow_read_packet and WaitForSingleObject (ctx->event,INFINITE);
Changed WaitForSingleObject (ctx->event,INFINITE) to:
DWORD r = WaitForSingleObject (ctx->event,20);
if (r == WAIT_TIMEOUT) {
int ret = 0;
long event_code, param1, param2;
while (IMediaEvent_GetEvent (ctx->media_event,&event_code,¶m1,¶m2) != E_ABORT) {
switch (event_code)
{
case EC_COMPLETE:
break;
case EC_DEVICE_LOST:
case EC_ERROR_ABORT:
ret = -1;
break;
}
IMediaEvent_FreeEventParams (event_code,param1,param2);
}
if (ret < 0)
return (-1);
}
Again the least elegant and probably least optimal but it was the quickest to do.
I will right this up as a ticket but I don't wish to waste time fighting with Carl about it. A consol app will close out the thread and no way to show it to you that way. There will be no backtrace etc.
More information about the ffmpeg-devel
mailing list