11-20-2012 04:00 PM
I'm having trouble getting MMRENDERER_STATE_CHANGE event code when my video ends in the VideoWindow sample.
I request the events with: mmrenderer_request_events(video_context_name
When I play the video the following events and nothing more: (with the pb_sample.mp4)
MMRENDERER_STATE_CHANGE: MMR_PLAYING
MMRENDERER_STATUS_UPDATE pos: 1001 speed: 0
...
...
MMRENDERER_STATUS_UPDATE pos: 8192 speed: 0
What do I need to do in order to get MMRENDERER_STATE_CHANGE when the playback finishes?
Best,
Shahrouz
Solved! Go to Solution.
11-21-2012 09:41 AM
11-21-2012 10:31 AM
There was a similar bug related to this, with mm-renderer. Are you both on the most recent Beta3 OS/SDK builds? (10.0.9.388 / 10.0.9.386)?
Thanks,
Rashid
11-21-2012 10:55 AM
Also, going forward, it is advisable to avoid BPS to process and track mmrenderer events. Instead, "mm/renderer/events.h" should be used. That is, mm-renderer has it owns event queue, which gives more information about the mmrenderer context than what you get through the BPS thread.
This is not documented right now (I am trying to get the documentation team to release the documentation ASAP). However, I am pasting some code below to show it can be used:
int errorWait;
const mmr_event_t* event;
int eventNum = 0;
for (;;) {
errorWait = mmr_event_wait( mmr_context );
if (errorWait != 0 ) {
//do error handling
fprintf (stdout,"ERROR : mmr_event_wait : errroWait = %d\n", errorWait);
}
// now, get the actual event
event= mmr_event_get( mmr_context);
switch (event->type) {
.......
case 1:
//TODO: handle event_error
break;
case 2:
// STATE change should come here
// NOTE: Query the state here by accessing and checking : event->state
break;
case 5:
//buffer status
const char *bufferstatus = strm_dict_find_value(event->data, "bufferstatus");
fprintf(stdout, "bufferstatus= %s\n", bufferstatus);
break;
case 6:
//metadata
const char *duration = strm_dict_find_value( event->data, "md_title_duration");
fprintf(stdout, "duration= %s\n", duration);
break;
....
}
11-21-2012 11:07 AM
Where can I find the enum values corresponding to the numbers you have in the switch case?
11-21-2012 11:10 AM
typedef enum mmr_event_type {
MMR_EVENT_NONE, ///< No pending events.
MMR_EVENT_ERROR, ///< Playback has stopped due to an error or EOF.
MMR_EVENT_STATE, ///< State or speed change, other than an error or EOF.
MMR_EVENT_OVERFLOW, ///< Some state changes lost; the event contains most the recent state.
MMR_EVENT_WARNING, ///< Warning event.
MMR_EVENT_STATUS, ///< Status update (position, buffer level, etc).
MMR_EVENT_METADATA, ///< Metadata update.
MMR_EVENT_PLAYLIST, ///< Playlist window update.
MMR_EVENT_INPUT, ///< An input has been attached or detached, or input parameters changed.
MMR_EVENT_OUTPUT, ///< An output has been attached or detached, or output parameters changed.
MMR_EVENT_CTXTPAR, ///< Context parameters have changed.
MMR_EVENT_TRKPAR, ///< Track parameters have changed.
MMR_EVENT_OTHER, ///< None of the above, but something has changed.
} mmr_event_type_t;
11-21-2012 11:13 AM
As xsacha also pasted, a lot of this info is in the header file I mentioned: "mm/renderer/events.h". It is probably the easiest to just navigate there, within the QNX Momentics IDE and check out the enum types and functions.
I am pasting some of the others as well:
/**
* The event type.
*/
typedef enum mmr_event_type {
MMR_EVENT_NONE, ///< No pending events.
MMR_EVENT_ERROR, ///< Playback has stopped due to an error or EOF.
MMR_EVENT_STATE, ///< State or speed change, other than an error or EOF.
MMR_EVENT_OVERFLOW, ///< Some state changes lost; the event contains most the recent state.
MMR_EVENT_WARNING, ///< Warning event.
MMR_EVENT_STATUS, ///< Status update (position, buffer level, etc).
MMR_EVENT_METADATA, ///< Metadata update.
MMR_EVENT_PLAYLIST, ///< Playlist window update.
MMR_EVENT_INPUT, ///< An input has been attached or detached, or input parameters changed.
MMR_EVENT_OUTPUT, ///< An output has been attached or detached, or output parameters changed.
MMR_EVENT_CTXTPAR, ///< Context parameters have changed.
MMR_EVENT_TRKPAR, ///< Track parameters have changed.
MMR_EVENT_OTHER, ///< None of the above, but something has changed.
} mmr_event_type_t;
/**
* The context state
*/
typedef enum mmr_state {
MMR_STATE_DESTROYED, ///< The context has been destroyed.
MMR_STATE_IDLE, ///< The context has no input.
MMR_STATE_STOPPED, ///< The context has an input but is not playing.
MMR_STATE_PLAYING, ///< The context is playing or paused.
} mmr_state_t;
/**
* The event structure.
*/
typedef struct mmr_event {
mmr_event_type_t type; ///< The event type
mmr_state_t state; ///< The context state -- valid even when type==MMR_EVENT_NONE
int speed; ///< The playback speed (0 means paused)
union mmr_event_details {
struct mmr_event_state {
mmr_state_t oldstate; ///< The state before the event
int oldspeed; ///< The speed before the event
} state; ///< When type is STATE
struct mmr_event_error {
mmr_error_info_t info; ///< The error info
} error; ///< When type is ERROR
struct mmr_event_warning {
const char *str; ///< The warning string, as a C string
const strm_string_t *obj; ///< The warning string, as a strm_string_t (shareable dictionary string)
} warning; ///< When type is WARNING
struct mmr_event_metadata {
unsigned index; ///< The playlist index for playlist-related events; otherwise, zero
} metadata; ///< When type is METADATA
struct mmr_event_trkparam {
unsigned index; ///< The playlist index
} trkparam; ///< When type is TRKPAR
struct mmr_event_playlist {
unsigned start; ///< The index of the first item in the window
unsigned end; ///< The index of the last item in the window
unsigned length; ///< The playlist length
} playlist; ///< When type is PLAYLIST
struct mmr_event_output {
unsigned id; ///< Output ID
} output; ///< When type is OUTPUT
} details;
const strm_string_t *pos_obj; ///< The position for STATUS, ERROR, and WARNING events; otherwise NULL
const char *pos_str; ///< The position for STATUS, ERROR, and WARNING events; otherwise NULL
const strm_dict_t *data; ///< The full content of the affected object (NULL if object deleted)
const char *objname; ///< The name of the affected object
void *usrdata; ///< The user data associated with this object, or NULL if new object
} mmr_event_t;
Cheers,
Rashid
11-21-2012 12:43 PM
Hi there Rashid,
I am running (10.0.9.388 / 10.0.9.386).
I'm still having problems with not getting a state change, even with mmr_event_wait():
for (;;)
{
int errorWait = mmr_event_wait(mmr_video_context);
if (errorWait != 0)
{
//do error handling
fprintf (stdout,"ERROR : mmr_event_wait : errroWait = %d\n", errorWait);
}
// now, get the actual event
const mmr_event_t * event = mmr_event_get(mmr_video_context);
switch (event->type)
{
case MMR_EVENT_NONE: ///< No pending events.
fprintf (stderr,"MMR_EVENT_NONE\n");
break;
case MMR_EVENT_ERROR: ///< Playback has stopped due to an error or EOF.
break;
case MMR_EVENT_STATE: ///< State or speed change, other than an error or EOF.
fprintf (stderr,"MMR_EVENT_STATE\n");
break;
case MMR_EVENT_OVERFLOW: ///< Some state changes lost; the event contains most the recent state.
fprintf (stderr,"MMR_EVENT_OVERFLOW\n");
break;
case MMR_EVENT_WARNING: ///< Warning event.
fprintf (stderr,"MMR_EVENT_WARNING\n");
break;
case MMR_EVENT_STATUS: ///< Status update (position, buffer level, etc).
fprintf (stderr,"MMR_EVENT_STATUS\n");
break;
case MMR_EVENT_METADATA: ///< Metadata update.
fprintf (stderr,"MMR_EVENT_METADATA\n");
break;
case MMR_EVENT_PLAYLIST: ///< Playlist window update.
fprintf (stderr,"MMR_EVENT_PLAYLIST\n");
break;
case MMR_EVENT_INPUT: ///< An input has been attached or detached, or input parameters changed.
fprintf (stderr,"MMR_EVENT_INPUT\n");
break;
case MMR_EVENT_OUTPUT: ///< An output has been attached or detached, or output parameters changed.
fprintf (stderr,"MMR_EVENT_OUTPUT\n");
break;
case MMR_EVENT_CTXTPAR: ///< Context parameters have changed.
fprintf (stderr,"MMR_EVENT_CTXTPAR\n");
break;
case MMR_EVENT_TRKPAR: ///< Track parameters have changed.
fprintf (stderr,"MMR_EVENT_TRKPAR\n");
break;
case MMR_EVENT_OTHER: ///< None of the above, but something has changed.
fprintf (stderr,"MMR_EVENT_OTHER\n");
break;
}
}
When I play the video and let it run until it finishes i get the following mmr_events:
MMR_EVENT_STATE
MMR_EVENT_INPUT
MMR_EVENT_CTXTPAR
MMR_EVENT_OUTPUT
MMR_EVENT_OUTPUT
MMR_EVENT_METADATA
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
MMR_EVENT_STATUS
I need a way to tell if I have reached the end of the video in a reliable way.
11-21-2012 02:26 PM
Hi shahrouz,
I just tried running a sample on the OS version you have and it does work for me. The code I pasted above was mainly to cover all the use cases needed; apologies for any confusion caused.
For figuring out the state, you don't need to do the *switch* case on the "event->type" for the *state*. Every mmr_event_t* has a *state* attribute associated with it. So you can do a switch case for the *state* for every event.
Essentially, after getting every event in the event *for loop*, the code would be like this:
printf("-------------------------type=%d, state = %d\n", event->type, event->state);
// switch case just for the state
switch (event->state) {
case 0:
printf(" -----------------------------MMR_STATE_DESTROYED \n");
break;
case 1:
printf(" -----------------------------MMR_STATE_IDLE \n");
break;
case 2:
printf(" -----------------------------MMR_STATE_STOPPED \n");
break;
case 3:
printf(" -----------------------------MMR_STATE_PLAYING \n");
break;
}
The resulting traces are this:
-------------------------type=2, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=8, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=10, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=9, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=9, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=6, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=5, state = 3
-----------------------------MMR_STATE_PLAYING
-------------------------type=1, state = 2
-----------------------------MMR_STATE_STOPPED
-------------------------type=5, state = 2
-----------------------------MMR_STATE_STOPPED
I got those enum types from the header files I mentioned: 'mm/renderer/events.h".
You should be able to track the playback state like this. Let us know if that helps.
Cheers,
Rashid
11-22-2012 02:54 PM
Thank you Rashid.
This was exactly what I needed.
Best,
Shahrouz