網頁

2016年5月17日 星期二

snapshot from sout

const char *const vlc_args[] = {
"-I=dummy",
"--vout=dummy",
"--network-caching=5000",
  "--sout=#duplicate{dst=display,dst=rtp{sdp=rtsp://:8554/ch1}}", "--sout-all", "--sout-keep",  "--verbose=2",
"--file-logging", logFile,
};
int vlc_argc = sizeof(vlc_args) / sizeof(vlc_args[0]);
vlcInstance = libvlc_new(vlc_argc, vlc_args);
const char *psz_mrl = "rtsp://169.254.1.168:554/live2.sdp";
media = libvlc_media_new_location(vlcInstance, psz_mrl);
mp = libvlc_media_player_new_from_media(media);
libvlc_media_release(media);
libvlc_media_player_play(mp);

snapshot 需要 input_resource_t, 所以重點是傳遞 input_resource_t 的位址
vi ../modules/stream_out/display.c
    p_sys->p_resource = input_resource_New( p_this );
    var_Create(p_stream, "sout-display-input-resource", VLC_VAR_ADDRESS);
    var_SetAddress(p_stream, "sout-display-input-resource", p_sys->p_resource);
    msg_Dbg(p_stream, "display.Open set input_resource_t(%p) to sout_stream_t SSS", p_sys->p_resource);

將 input_resource_t 的位址,從 sout_stream_t 傳到 sout_instance_t
vi ../src/stream_output/stream_output.c
static sout_stream_t *sout_StreamNew( sout_instance_t *p_sout, char *psz_name,
                               config_chain_t *p_cfg, sout_stream_t *p_next)
{
    p_stream->p_module =
        module_need( p_stream, "sout stream", p_stream->psz_name, true );
    input_resource_t *p_resource = var_GetAddress(p_stream, "sout-display-input-resource");
    if (p_resource != NULL) {
        var_Create(p_sout, "sout-display-input-resource", VLC_VAR_ADDRESS);
        var_SetAddress(p_sout, "sout-display-input-resource", p_resource);
        msg_Dbg(p_sout, "stream_output:sout_StreamNew set input_resource_t(%p) from sout_stream_t to sout_instance_t SSS", p_resource);
    }
}

將 input_resource_t 的位址,從 sout_instance_t 傳到 input_thread_t
vi ../src/input/input.c
static int Init( input_thread_t * p_input )
{
    if (p_input->p->p_sout) {
        input_resource_t *p_resource = var_GetAddress(p_input->p->p_sout, "sout-display-input-resource");
        if (p_resource != NULL) {
            var_Create(p_input, "sout-display-input-resource", VLC_VAR_ADDRESS);
            var_SetAddress(p_input, "sout-display-input-resource", p_resource);
            msg_Dbg(p_input, "input.Init send input_resource_t(%p) from input_thread_t->p->p_sout to input_thread_t SSS", p_resource);
        }
    }
}

snapshot 是利用 vout_thread_t
vi ../lib/video.c
int libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, unsigned num,
                            const char *psz_filepath,
                            unsigned int i_width, unsigned int i_height )
{
    vout_thread_t *p_vout = GetVout (p_mi, num);
}
GetVout -> GetVouts -> input_Control(INPUT_GET_VOUTS) -> input_vaControl

利用 input_resource_HoldVouts, 取得 vout_thread_t
vi ../src/input/control.c
int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
{
        case INPUT_GET_VOUTS:
        {
            vout_thread_t ***ppp_vout = (vout_thread_t***)va_arg( args, vout_thread_t*** );
            size_t        *pi_vout = va_arg( args, size_t * );

            input_resource_HoldVouts( p_input->p->p_resource, ppp_vout, pi_vout );
            if( *pi_vout <= 0 ) { // 找不到,更換另一個 input_resource_t
                input_resource_t *p_resource = var_GetAddress(p_input, "sout-display-input-resource");
                msg_Dbg(p_input, "control.input_vaControl input_resource_HoldVouts(sout-display-input-resource) SSS");
                input_resource_HoldVouts(p_resource, ppp_vout, pi_vout);
            }
            if( *pi_vout <= 0 ) {
                return VLC_EGENERIC;
            }
            return VLC_SUCCESS;
        }
}

沒有留言:

張貼留言