Response events in DirectShow

zhaozj2021-02-08  407

Response Event We explain how to respond to events in file playback. The following will provide approximately 25 new codes to illustrate this problem. First, let's talk about how the event notification works during the DirectShow application running, the filter status changes. For example, it may play from a suspension, or encounter an error in the stream, or request a video window redrawing, etc. In order to make the filter graphics manager can be changed, the filter will send an event, consisting of a corresponding event code, which represents a type of event. All of the events are listed below:

EC_AC_ACTIVATE video window is activated or converted into an inactive state EC_Buffering_data filtering graphic containing buffer data EC_CLOCK_CHANGED reference clock is changed EC_CLOCK_UNSET clock provider is disconnected EC_COMPLETE All data is rendered EC_DEVICE_LOST One plug and play device is removed or become effective. EC_DISPLAY_CHANGED display mode is changed EC_END_OF_SEGMENT reaches the end of a segment .EC_ERROR_STILLPLAYING EC_ERRORABORT a command fails asynchronous operation is not supported EC_FULLSCREEN_LOST abandoned EC_EXTDEVICE_MODE_CHANGE a video rendering window is switched out of the full-screen mode is changed .EC_GRAPH_CHANGED FIG EC_LENGTH_CHANGED filter length of the source is changed filtered .EC_NEED_RESTART Request Filtering Graph Restart. EC_NOTIFY_WINDOW Nanded a filter EC_OLE_EVENT filter for a video rendering window Pass a string to the application. .Ec_opening_file filtering map Opens a file, or has completed the file operation EC_PALETTE_CHANGED video palette is changed. EC_PAUSED a pause request is processed. EC_QUALITY_CHANGE Filter map For quality control loss EC_REPAINT A video renderer requires redrawing .ec_segment_started a new Segment start EC_SHUTTING_DOWN filter diagram is turned off EC_SNDDEV_IN_ERROR an input pin error. EC_SNDDEV_OUT_ERROR An audio device output pin error. EC_STARVATION Filter does not get enough data. EC_STATE_CHANGE Filter diagram Status change EC_STEP_COMPLETE A filter executed Jeong progressive EC_STREAM_CONTROL_STARTED flow control start command to have an effect .EC_STREAM_CONTROL_STOPPED a stop command control of an effect EC_STREAM_ERROR_STILLPLAYING generates an error in the flow stream, but the stream still in operation .EC_STREAM_ERROR_STOPPED a stream stopped by an error EC_TIMECODE_AVAILABLE does not support EC_USERABORT user interrupt playback. EC_VIDEO_SIZE_CHANGED Local Video Size Change. EC_Window_Destroyed Video Render is destroyed, or removed from the filter diagram. Filtering Graphics Manager sometimes processes some events that do not report to the application, for example, request to redraw the event of the video window. DirectShow's event response mechanism is very like a message loop under Windows. In fact, when a new event occurs, you can send a Windows message to the specified window. The application then handles this event from the Windows message loop. Using an event notified the following example code processes a message loop from the main window. This message is the user's own definition, WM_APP is the bottom line sign of a user message, the number of messages identified by the application is WM_APP to 0xBFFF. As follows: #define WM_GRAPHNOTIFY WM_APP 1 Set the filter graphic manager to submit this message to the application's main window: pevent-> setNotifyWindow (OAHWND) G_hWnd, WM_GraphNotify, 0); IMEDIAEVENTEX :: setNotifyWindow method specifies a window (G_hwnd) as a container for receiving a message. This method needs to be called after the creation of the filtered graphics manager and the specified play window, but must be played before playing.

To respond to the message we need to add this message in WindowProc: Case WM_GraphNotify: HandleEvent (); Break; In the process of handle, we can call iMediaEvent :: getEvent method to get events from the loop: Long Evcode, Param1, Param2; HRESULT HR; if (pevent == null) return; whilevent (& Evcode, & param1, & param2, 0), succeeded (hr)) {hr = pevent-> freeeventparams (Evcode, param1, param2); if ((EC_COMPLETE == EVCODE) || (EC_USERABORT == EVCode))) {cleanup (); Break;}} Because event is asynchronous processing, there may be many messages need to be processed, we have to call getEvent to get the message, Until the return value is a failure code, it will prove that the message signal is empty. Since their parameters may be a BSTR type data (this is the data type that needs to be allocated in ATL). So we have to release them (iMediaEvent :: FreeEventParams). When an EC_COMPLETE event occurs, the filtering graphic manager does not switch to the stop state. This must be controlled by the application. When the application releases the iMediaEventEx pointer, it must set the setNotifyWindow to cancel the event notification. Pevent-> setNotifyWindow (NULL, 0, 0); pevent-> release (); pevent = null; below is a complete example: #include #include #define WM_GRAPHNOTIFY WM_APP 1 #define classname "EventNotify"

IgraphBuilder * pgraph = null; iMediacontrol * pmediacontrol = null; iMediaeventEx * pevent = null; ivideowindow * pvidwin = null; hwnd g_hwnd;

Void PlayFile (Void) {COCREATEINSTANCE (CLSID_FILTERGRAPH, NULL, CLSCTX_INPROC, IID_IGRAPHBUILDER, (Void **) & pgraph); pgraph-> renderfile (l "c: //media//boys.avi", null);

PGRAPH-> Queryinterface (IID_IVideoWindow, (void **) & pvidwin; pvidwin-> put_owner (oahwnd) g_hwnd); pvidwin-> put_windowstyle (WS_CHILD | WS_CLIPSIBLINGS);

PGRAPH-> Queryinterface (IID_IMEDIAEVENTEX, (Void **) & pevent); pevent-> setNotifyWindow (OAHWND) G_HWND, WM_GRAPHNOTIFY, 0);

Pgraph-> queryinterface (IID_IMEDIACONTROL, (Void **) & pmediacontrol); pmediacontrol-> run ();} void cleanup (void) {pvidwin-> put_visible (oafalse); pvidwin-> put_owner (null);

Pevent-> setNotifyWindow (NULL, 0, 0); pevent-> release (); pevent = null;

// stop the graph. Pmediacontrol-> stop ();

Pmediacontrol-> release (); pvidwin-> release (); pgraph-> release (); postquitmessage (0);

Void Handleevent () {Long Evcode, Param1, Param2; HRESULT HR

IF (PEVENT == Null) Return;

While (HR = pevent-> getEvent (& Evcode, & param1, & param2, 0), succeeded (hr)) {hr = pevent-> freeeventparams (Evcode, Param1, Param2); if ((EC_COMPLETE == EVCode) || (EC_USERABORT == EVCODE)) {cleanup (); break;}}}

/ * WINDOWPROC function is here: Case WM_GraphNotify: Handleevent (); Break;

转载请注明原文地址:https://www.9cbs.com/read-993.html

New Post(0)