Ignore:
Timestamp:
Dec 30, 2010 4:31:16 PM (11 years ago)
Author:
ming
Message:

Re #1184: Adding pjmedia_clock_src for the purpose of audio and video synchronization and also to provide synchronization mechanism between two medias in general.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/aviplay.c

    r3401 r3402  
    9191{ 
    9292    pjmedia_vid_port   *vid_port; 
    93     pjmedia_aud_stream *aud_stream; 
     93    pjmedia_snd_port   *snd_port; 
    9494    pj_bool_t           is_running; 
    9595    pj_bool_t           is_quitting; 
     
    105105    pjmedia_converter   *conv; 
    106106} codec_port_data_t; 
    107  
    108 static pj_status_t avi_play_cb(void *user_data, pjmedia_frame *frame) 
    109 { 
    110     return pjmedia_port_get_frame((pjmedia_port*)user_data, frame); 
    111 } 
    112107 
    113108static pj_status_t avi_event_cb(pjmedia_vid_stream *stream, 
     
    126121        if (ap->is_running) { 
    127122            pjmedia_vid_port_stop(ap->vid_port); 
    128             if (ap->aud_stream) 
    129                 pjmedia_aud_stream_stop(ap->aud_stream); 
     123            if (ap->snd_port) 
     124                pjmedia_aud_stream_stop( 
     125                    pjmedia_snd_port_get_snd_stream(ap->snd_port)); 
    130126        } else { 
    131127            pjmedia_vid_port_start(ap->vid_port); 
    132             if (ap->aud_stream) 
    133                 pjmedia_aud_stream_start(ap->aud_stream); 
     128            if (ap->snd_port) 
     129                pjmedia_aud_stream_start( 
     130                    pjmedia_snd_port_get_snd_stream(ap->snd_port)); 
    134131        } 
    135132        ap->is_running = !ap->is_running; 
     
    187184    pjmedia_vid_port *renderer=NULL; 
    188185    pjmedia_vid_port_param param; 
    189     pjmedia_aud_param aparam; 
    190186    const pjmedia_video_format_info *vfi; 
    191187    pjmedia_video_format_detail *vfd; 
    192     pjmedia_audio_format_detail *afd; 
    193     pjmedia_aud_stream *strm = NULL; 
     188    pjmedia_snd_port *snd_port = NULL; 
    194189    pj_status_t status; 
    195190    int rc = 0; 
     
    376371     
    377372    if (aud_port) { 
    378         status = pjmedia_aud_dev_default_param( 
    379                      PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV, 
    380                      &aparam); 
     373        /* Create sound player port. */ 
     374        status = pjmedia_snd_port_create_player(  
     375                 pool,                              /* pool                 */ 
     376                 -1,                                /* use default dev.     */ 
     377                 PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate.          */ 
     378                 PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels.       */ 
     379                 PJMEDIA_PIA_SPF(&aud_port->info),  /* samples per frame.   */ 
     380                 PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample.     */ 
     381                 0,                                 /* options              */ 
     382                 &snd_port                          /* returned port        */ 
     383                 ); 
    381384        if (status != PJ_SUCCESS) { 
    382385            rc = 310; goto on_return; 
    383386        } 
    384387         
    385         aparam.dir = PJMEDIA_DIR_PLAYBACK; 
    386         afd = pjmedia_format_get_audio_format_detail(&aud_port->info.fmt, 
    387                                                      PJ_TRUE); 
    388         aparam.clock_rate = afd->clock_rate; 
    389         aparam.channel_count = afd->channel_count; 
    390         aparam.bits_per_sample = afd->bits_per_sample; 
    391         aparam.samples_per_frame = afd->frame_time_usec * aparam.clock_rate * 
    392                                    aparam.channel_count / 1000000; 
    393          
    394         status = pjmedia_aud_stream_create(&aparam, NULL, &avi_play_cb, 
    395                                            aud_port, 
    396                                            &strm); 
    397         if (status != PJ_SUCCESS) { 
    398             rc = 320; goto on_return; 
    399         } 
    400          
    401         /* Start audio streaming.. */ 
    402         status = pjmedia_aud_stream_start(strm); 
     388        /* Connect file port to the sound player. 
     389         * Stream playing will commence immediately. 
     390         */ 
     391        status = pjmedia_snd_port_connect(snd_port, aud_port); 
    403392        if (status != PJ_SUCCESS) { 
    404393            rc = 330; goto on_return; 
     
    411400        pj_bzero(&cb, sizeof(cb)); 
    412401        cb.on_event_cb = avi_event_cb; 
    413         avi_port.aud_stream = strm; 
     402        avi_port.snd_port = snd_port; 
    414403        avi_port.vid_port = renderer; 
    415404        avi_port.is_running = PJ_TRUE; 
    416405        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port); 
     406 
     407        if (snd_port) { 
     408            /* Synchronize video rendering and audio playback */ 
     409            pjmedia_vid_port_set_clock_src( 
     410                renderer, PJMEDIA_DIR_RENDER, 
     411                pjmedia_snd_port_get_clock_src( 
     412                    snd_port, PJMEDIA_DIR_PLAYBACK)); 
     413        } 
     414                                               
    417415         
    418416        /* Start video streaming.. */ 
     
    428426 
    429427on_return: 
    430     if (strm) { 
    431         pjmedia_aud_stream_stop(strm); 
    432         pjmedia_aud_stream_destroy(strm); 
     428    if (snd_port) { 
     429        pjmedia_snd_port_disconnect(snd_port); 
     430        /* Without this sleep, Windows/DirectSound will repeteadly 
     431         * play the last frame during destroy. 
     432         */ 
     433        pj_thread_sleep(100); 
     434        pjmedia_snd_port_destroy(snd_port); 
    433435    } 
    434436    if (renderer) 
    435437        pjmedia_vid_port_destroy(renderer); 
     438    if (aud_port) 
     439        pjmedia_port_destroy(aud_port); 
    436440    if (vid_port) 
    437441        pjmedia_port_destroy(vid_port); 
Note: See TracChangeset for help on using the changeset viewer.