Exemplo n.º 1
0
Bool validator_on_event_record(void *udta, GF_Event *event, Bool consumed_by_compositor)
{
	GF_Validator *validator = (GF_Validator *)udta;
	Bool rec_event = 1;
	switch (event->type) {
	case GF_EVENT_CONNECT:
		if (event->connect.is_connected) {
			if (!validator->trace_mode) {
				gf_sc_add_video_listener(validator->term->compositor, &validator->video_listener);
			}
			validator->ck = validator->term->root_scene->scene_codec ? validator->term->root_scene->scene_codec->ck : validator->term->root_scene->dyn_ck;
		}
		break;
	case GF_EVENT_KEYDOWN:
		if (event->key.key_code == GF_KEY_INSERT) {
			rec_event = 0;
		} else if (event->key.key_code == GF_KEY_PAGEDOWN) {
			rec_event = 0;
		} else if (event->key.key_code == GF_KEY_PAGEUP) {
			rec_event = 0;
		} else if (event->key.key_code == GF_KEY_END) {
			rec_event = 0;
		} else if (event->key.key_code == GF_KEY_CONTROL) {
			rec_event = 0;
		} else if (event->key.flags & GF_KEY_MOD_CTRL) {
			rec_event = 0;
		}
		break;
	case GF_EVENT_KEYUP:
		if (event->key.flags & GF_KEY_MOD_CTRL) {
			rec_event = 0;
			if (event->key.key_code == GF_KEY_INSERT) {
				char *snap_name = validator_create_snapshot(validator);
				validator_xvs_add_snapshot_node(validator, snap_name, gf_clock_time(validator->ck));
				gf_free(snap_name);
			} else if (event->key.key_code == GF_KEY_END) {
				GF_Event evt;
				memset(&evt, 0, sizeof(GF_Event));
				evt.type = GF_EVENT_QUIT;
				validator->term->compositor->video_out->on_event(validator->term->compositor->video_out->evt_cbk_hdl, &evt);
			} else if (event->key.key_code == GF_KEY_F1) {
				validator->snapshot_next_frame = 1;
			}
		} else if (event->key.key_code == GF_KEY_PAGEDOWN) {
			rec_event = 0;
			validator_xvs_close(validator);
			gf_term_disconnect(validator->term);
			gf_sc_remove_video_listener(validator->term->compositor, &validator->video_listener);
			validator_xvs_next(validator, 0);
		} else if (event->key.key_code == GF_KEY_PAGEUP) {
			rec_event = 0;
			validator_xvs_close(validator);
			gf_term_disconnect(validator->term);
			gf_sc_remove_video_listener(validator->term->compositor, &validator->video_listener);
			validator_xvs_next(validator, 1);
		} else if (event->key.key_code == GF_KEY_CONTROL) {
			rec_event = 0;
		}
		break;
	}
	if (rec_event) {
		validator_xvs_add_event_dom(validator, event);
	}
	return 0;
}
Exemplo n.º 2
0
static Bool validator_process(GF_TermExt *termext, u32 action, void *param)
{
	const char *opt;
	GF_Validator *validator = termext->udta;

	switch (action) {

	/* Upon starting of the terminal, we parse (possibly an XVL file), an XVS file, and start the first test sequence */
	case GF_TERM_EXT_START:
		validator->term = (GF_Terminal *) param;

		/* if the validator is loaded, we switch off anti-aliasing for image comparison and we put a low framerate,
		but we store the previous value to restore it upon termination of the validator */
		opt = (char *)gf_modules_get_option((GF_BaseInterface*)termext, "Compositor", "FrameRate");
		if (opt) validator->prev_fps = gf_strdup(opt);
		opt = (char *)gf_modules_get_option((GF_BaseInterface*)termext, "Compositor", "AntiAlias");
		if (opt) validator->prev_alias = gf_strdup(opt);

		/* Check if the validator should be loaded and in which mode */
		opt = gf_modules_get_option((GF_BaseInterface*)termext, "Validator", "Mode");
		if (!opt) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("Validator missing configuration, stopping.\n"));
			return 0;
		} else if (!strcmp(opt, "Play")) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator starting in playback mode.\n"));
			validator->is_recording = 0;
		} else if (!strcmp(opt, "Record")) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator starting in recording mode.\n"));
			validator->is_recording = 1;
		} else if (!strcmp(opt, "Disable")) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator is disabled.\n"));
			return 0;
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("Validator configuration using wrong mode, stopping.\n"));
			return 0;
		}

		/* initializes the validator and starts */
		validator->xvs_filename = NULL;
		validator->xvl_filename = (char *)gf_modules_get_option((GF_BaseInterface*)termext, "Validator", "XVL");
		if (!validator->xvl_filename) {
			validator->xvs_filename = (char *)gf_modules_get_option((GF_BaseInterface*)termext, "Validator", "XVS");
			if (!validator->xvs_filename) {
				validator->xvs_filename = (char *)gf_modules_get_option((GF_BaseInterface*)termext, "Validator", "Trace");
				if (!validator->xvs_filename) {
					GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("Validator configuration without input, stopping.\n"));
					return 0;
				}
				validator->test_filename = validator->xvs_filename;
				validator->trace_mode = 1;
				GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator using trace file: %s\n", validator->xvs_filename));
			} else {
				GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator using scenario file: %s\n", validator->xvs_filename));
			}
		} else {
			GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Validator using scenario playlist: %s\n", validator->xvl_filename));
		}

		/* since we changed parameters of the compositor, we need to trigger a reconfiguration */
//		gf_modules_set_option((GF_BaseInterface*)termext, "Compositor", "FrameRate", "5.0");
//		gf_modules_set_option((GF_BaseInterface*)termext, "Compositor", "AntiAlias", "None");
//		gf_term_set_option(validator->term, GF_OPT_RELOAD_CONFIG, 1);

		/* TODO: if start returns 0, the module is not loaded, so the above init (filter registration) is not removed,
		   should probably return 1 all the time, to make sure stop is called */
		if (validator->xvl_filename) {
			validator_xvl_open(validator);
			if (!validator->xvl_node) {
				return 0;
			}
			validator_xvs_next(validator, 0);
			if (!validator->xvs_node) {
				return 0;
			}
		} else if (validator->xvs_filename) {
			validator_xvs_open(validator);
			if (!validator->xvs_node) {
				return 0;
			}
			if (validator->test_filename) {
				validator_test_open(validator);
			} else {
				validator_xvs_close(validator);
				return 0;
			}
		} else {
			return 0;
		}

		validator->evt_filter.udta = validator;
		if (!validator->is_recording) {
			validator->evt_filter.on_event = validator_on_event_play;
			termext->caps |= GF_TERM_EXTENSION_NOT_THREADED;
		} else {
			validator->evt_filter.on_event = validator_on_event_record;
		}
		gf_term_add_event_filter(validator->term, &validator->evt_filter);
		validator->video_listener.udta = validator;
		validator->video_listener.on_video_frame = validator_on_video_frame;
		validator->video_listener.on_video_reconfig = validator_on_video_reconfig;


		if (!validator->is_recording) {
			validator_load_event(validator);
		}
		return 1;

	/* when the terminal stops, we close the XVS parser and XVL parser if any, restore the config,
	and free all validator data (the validator will be destroyed when the module is unloaded)
	Note: we don't need to disconnect the terminal since it's already stopping */
	case GF_TERM_EXT_STOP:
		gf_term_remove_event_filter(validator->term, &validator->evt_filter);
		validator_xvs_close(validator);
		validator_xvl_close(validator);
		validator->term = NULL;
		if (validator->test_base) {
			gf_free(validator->test_base);
			validator->test_base = NULL;
		}
		/*auto-disable the recording by default*/
		if (!validator->trace_mode) {
			if (validator->is_recording ) {
				gf_modules_set_option((GF_BaseInterface*)termext, "Validator", "Mode", "Play");
			} else {
				gf_modules_set_option((GF_BaseInterface*)termext, "Validator", "Mode", "Disable");
			}
		}
		GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("Stopping validator\n"));
		if (validator->prev_fps) {
			gf_modules_set_option((GF_BaseInterface*)termext, "Compositor", "FrameRate", validator->prev_fps);
			gf_free(validator->prev_fps);
			validator->prev_fps = NULL;
		}
		if (validator->prev_alias) {
			gf_modules_set_option((GF_BaseInterface*)termext, "Compositor", "AntiAlias", validator->prev_alias);
			gf_free(validator->prev_alias);
			validator->prev_alias = NULL;
		}
		break;

	/* When called in the main loop of the terminal, we don't do anything in the recording mode.
	   In the playing/validating mode, we need to check if an event needs to be dispatched or if snapshots need to be made,
	   until there is no more event, in which case we trigger either the load of the next XVS or the quit */
	case GF_TERM_EXT_PROCESS:
		/* if the time is right, dispatch the event and load the next one */
		while (!validator->is_recording && validator->evt_loaded && validator->ck && (validator->next_time <= gf_clock_time(validator->ck) )) {
			Bool has_more_events;
			//u32 diff = gf_clock_time(validator->ck) - validator->next_time;
			//GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[Validator] Time diff: evt_time=%d  clock_time = %d, diff=%d\n", validator->next_time, gf_clock_time(validator->ck), diff));
			if (validator->next_event_snapshot) {
				Bool res;
				char *snap_name = validator_create_snapshot(validator);
				gf_free(snap_name);
				res = validator_compare_snapshots(validator);
				validator->xvs_result &= res;
				validator->next_event_snapshot = 0;
			} else {
				validator->term->compositor->video_out->on_event(validator->term->compositor->video_out->evt_cbk_hdl, &validator->next_event);
			}
			has_more_events = validator_load_event(validator);
			if (!has_more_events) {
				validator_xvs_close(validator);
                if (! validator->trace_mode) {
                    gf_term_disconnect(validator->term);
                    gf_sc_remove_video_listener(validator->term->compositor, &validator->video_listener);
                    validator_xvs_next(validator, 0);
                    if (!validator->xvs_node) {
                        GF_Event evt;
                        memset(&evt, 0, sizeof(GF_Event));
                        evt.type = GF_EVENT_QUIT;
                        validator->term->compositor->video_out->on_event(validator->term->compositor->video_out->evt_cbk_hdl, &evt);
                    } else {
                        if (!validator->is_recording) {
                            validator_load_event(validator);
                        }
                    }
				}
			}
		}
		break;
	}
	return 0;
}
Exemplo n.º 3
0
/**
 * This thread sends the frame to TS mux
 * \param Parameter The GF_AVRedirect pointer
 */
static Bool video_encoding_thread_run(void *param)
{
    GF_AVRedirect * avr = (GF_AVRedirect*) param;
    u64 currentFrameTimeProcessed = 0;
    u32 lastEncodedFrameTime = 0;
    AVCodecContext * ctx = NULL;
    assert( avr );
    gf_sc_add_video_listener ( avr->term->compositor, &avr->video_listen );
    while (avr->is_running && (!ctx || !avr->swsContext)) {
        ctx = ts_get_video_codec_context(avr->ts_implementation);
        gf_sleep(16);
    }
    if (!ctx) {
        goto exit;
    }
    printf("******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start);
    while (avr->is_running) {
        {
            gf_mx_p(avr->frameMutex);
            while (!avr->frameTime || currentFrameTimeProcessed == avr->frameTime) {
                gf_mx_v(avr->frameMutex);
                if (!avr->is_running) {
                    goto exit;
                }
                gf_mx_p(avr->frameMutex);
				gf_sleep(1);
            }
            assert( currentFrameTimeProcessed != avr->frameTime);
            currentFrameTimeProcessed = avr->frameTime;
            {
                avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight );
                assert( avr->swsContext );
                sws_scale ( avr->swsContext,
#ifdef USE_AVCODEC2
                            ( const uint8_t * const * )
#else
                            ( uint8_t ** )
#endif /* USE_AVCODEC2 */
                            avr->RGBpicture->data, avr->RGBpicture->linesize,
                            0, avr->srcHeight,
                            avr->YUVpicture->data, avr->YUVpicture->linesize );
#ifdef AVR_DUMP_RAW_AVI
                if ( AVI_write_frame ( avr->avi_out, avr->frame, avr->size, 1 ) <0 )
                {
                    GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error writing video frame\n" ) );
                }
#endif /* AVR_DUMP_RAW_AVI */
                gf_mx_v(avr->frameMutex);
                if (avr->encode)
                {
                    int written;
                    //u32 sysclock = gf_sys_clock();
                    avr->YUVpicture->pts = currentFrameTimeProcessed;
                    //printf("Encoding frame PTS="LLU", frameNum=%u, time=%u...", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed);
                    written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture );
                    //ctx->coded_frame->pts = currentFrameTimeProcessed;
                    if ( written < 0 )
                    {
                        GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while encoding video frame =%d\n", written ) );
                    } else
                        if ( written > 0 )
                        {
                            ts_encode_video_frame(avr->ts_implementation, avr->videoOutbuf, written);
                        }
                    lastEncodedFrameTime = currentFrameTimeProcessed;
                }
            }
        }
        avr->frameTimeEncoded = currentFrameTimeProcessed;
		gf_sleep(1);
    } /* End of main loop */
exit:
    GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending video encoding thread...\n"));
    if (avr->term)
        gf_sc_remove_video_listener ( avr->term->compositor, &avr->video_listen );
    return 0;
}