Ignore:
Timestamp:
Dec 20, 2010 11:02:48 AM (12 years ago)
Author:
ming
Message:

Fixed #1184:

  • Move the AVI playback from pjmedia-test to new aviplay.c sample application
  • Take the input file from cmdline
  • Synchronize audio and video
  • Remove all codecs related hardcodes from the file

Re #1193: (no. 6: duplicate fps and frame_rate in pjmedia_format and pjmedia_vid_param)

  • Remove the frame_rate in pjmedia_vid_param
  • Use pjmedia_format's fps in videoport, sdl_dev, and colorbar_dev
  • Prevent overflow in ptime calculation from frame_rate
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c

    r3395 r3401  
    3838#define THIS_FILE "vid_dev_test.c" 
    3939 
    40 pj_status_t pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr, 
    41                                               pj_pool_t *pool); 
    42  
    43 typedef struct codec_port_data_t 
    44 { 
    45     pjmedia_vid_codec   *codec; 
    46     pjmedia_port        *src_port; 
    47     pj_uint8_t          *enc_buf; 
    48     pj_size_t            enc_buf_size; 
    49  
    50     pjmedia_converter   *conv; 
    51 } codec_port_data_t; 
    52  
    53 typedef struct avi_port_t 
    54 { 
    55     pjmedia_vid_port   *vid_port; 
    56     pjmedia_aud_stream *aud_stream; 
    57     pj_bool_t           is_running; 
    58 } avi_port_t; 
     40static pj_bool_t is_quitting = PJ_FALSE; 
    5941 
    6042static int enum_devs(void) 
     
    7658} 
    7759 
    78 static pj_status_t avi_play_cb(void *user_data, pjmedia_frame *frame) 
    79 { 
    80     return pjmedia_port_get_frame((pjmedia_port*)user_data, frame); 
    81 } 
    82  
    83 static pj_status_t avi_event_cb(pjmedia_vid_stream *stream, 
     60static pj_status_t vid_event_cb(pjmedia_vid_stream *stream, 
    8461                                void *user_data, 
    8562                                pjmedia_vid_event *event) 
    8663{ 
    87     avi_port_t *ap = (avi_port_t *)user_data; 
    88  
    8964    PJ_UNUSED_ARG(stream); 
    90  
    91     if (event->event_type != PJMEDIA_EVENT_MOUSEBUTTONDOWN) 
    92         return PJ_SUCCESS; 
    93  
    94     if (ap->is_running) { 
    95         pjmedia_vid_port_stop(ap->vid_port); 
    96         if (ap->aud_stream) 
    97             pjmedia_aud_stream_stop(ap->aud_stream); 
    98     } else { 
    99         pjmedia_vid_port_start(ap->vid_port); 
    100         if (ap->aud_stream) 
    101             pjmedia_aud_stream_start(ap->aud_stream); 
    102     } 
    103     ap->is_running = !ap->is_running; 
    104  
    105     /* We handled the event on our own, so return non-PJ_SUCCESS here */ 
     65    PJ_UNUSED_ARG(user_data); 
     66     
     67    if (event->event_type == PJMEDIA_EVENT_WINDOW_CLOSE) 
     68        is_quitting = PJ_TRUE; 
     69 
     70    /* We will handle the event on our own, so return non-PJ_SUCCESS here */ 
    10671    return -1; 
    107 } 
    108  
    109 static pj_status_t codec_get_frame(pjmedia_port *port, 
    110                                    pjmedia_frame *frame) 
    111 { 
    112     codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata; 
    113     pjmedia_vid_codec *codec = port_data->codec; 
    114     pjmedia_frame enc_frame; 
    115     pj_status_t status; 
    116  
    117     enc_frame.buf = port_data->enc_buf; 
    118     enc_frame.size = port_data->enc_buf_size; 
    119  
    120     if (port_data->conv) { 
    121         pj_size_t frame_size = frame->size; 
    122  
    123         status = pjmedia_port_get_frame(port_data->src_port, frame); 
    124         if (status != PJ_SUCCESS) goto on_error; 
    125  
    126         status = codec->op->decode(codec, frame, frame->size, &enc_frame); 
    127         if (status != PJ_SUCCESS) goto on_error; 
    128  
    129         frame->size = frame_size; 
    130         status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame); 
    131         if (status != PJ_SUCCESS) goto on_error; 
    132  
    133         return PJ_SUCCESS; 
    134     } 
    135  
    136     status = pjmedia_port_get_frame(port_data->src_port, &enc_frame); 
    137     if (status != PJ_SUCCESS) goto on_error; 
    138  
    139     status = codec->op->decode(codec, &enc_frame, frame->size, frame); 
    140     if (status != PJ_SUCCESS) goto on_error; 
    141  
    142     return PJ_SUCCESS; 
    143  
    144 on_error: 
    145     pj_perror(3, THIS_FILE, status, "codec_get_frame() error"); 
    146     return status; 
    147 } 
    148  
    149 static int aviplay_test(pj_pool_t *pool) 
    150 { 
    151     pjmedia_vid_port *renderer=NULL; 
    152     pjmedia_vid_port_param param; 
    153     pjmedia_aud_param aparam; 
    154     pjmedia_video_format_detail *vfd; 
    155     pjmedia_audio_format_detail *afd; 
    156     pjmedia_aud_stream *strm = NULL; 
    157     pj_status_t status; 
    158     int rc = 0; 
    159     pjmedia_avi_streams *avi_streams; 
    160     pjmedia_avi_stream *vid_stream, *aud_stream; 
    161     pjmedia_port *vid_port = NULL, *aud_port = NULL; 
    162     pjmedia_vid_codec *codec=NULL; 
    163     avi_port_t avi_port; 
    164 #if PJ_WIN32 
    165     const char *fname = "C:\\Users\\Liong Sauw Ming\\Desktop\\piratesmjpg.avi"; 
    166 #else 
    167     const char *fname = "/home/bennylp/Desktop/installer/video/movies/pirates.avi"; 
    168 #endif 
    169  
    170     pj_bzero(&avi_port, sizeof(avi_port)); 
    171  
    172     status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams); 
    173     if (status != PJ_SUCCESS) { 
    174         PJ_PERROR(2,("", status, "    Error playing %s (ignored)", fname)); 
    175         rc = 210; goto on_return; 
    176     } 
    177  
    178     vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams, 
    179                                                          0, 
    180                                                          PJMEDIA_TYPE_VIDEO); 
    181     vid_port = pjmedia_avi_stream_get_port(vid_stream); 
    182  
    183     if (vid_port) { 
    184         pjmedia_vid_port_param_default(&param); 
    185  
    186         status = pjmedia_vid_dev_default_param(pool, 
    187                                                PJMEDIA_VID_DEFAULT_RENDER_DEV, 
    188                                                &param.vidparam); 
    189         if (status != PJ_SUCCESS) { 
    190             rc = 220; goto on_return; 
    191         } 
    192  
    193         /* Create renderer, set it to active  */ 
    194         param.active = PJ_TRUE; 
    195         param.vidparam.dir = PJMEDIA_DIR_RENDER; 
    196         vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt, 
    197                                                      PJ_TRUE); 
    198         pjmedia_format_init_video(&param.vidparam.fmt,  
    199                                   vid_port->info.fmt.id, 
    200                                   vfd->size.w, vfd->size.h, 
    201                                   vfd->fps.num, vfd->fps.denum); 
    202  
    203         if (vid_port->info.fmt.id == PJMEDIA_FORMAT_MJPEG || 
    204             vid_port->info.fmt.id == PJMEDIA_FORMAT_H263) 
    205         { 
    206             /* Prepare codec */ 
    207             pj_str_t codec_id_st; 
    208             unsigned info_cnt = 1, i, k; 
    209             const pjmedia_vid_codec_info *codec_info; 
    210             pj_str_t port_name = {"codec", 5}; 
    211             pj_uint8_t *enc_buf = NULL; 
    212             pj_size_t enc_buf_size = 0; 
    213             pjmedia_vid_dev_info rdr_info; 
    214             pjmedia_port codec_port; 
    215             codec_port_data_t codec_port_data; 
    216             pjmedia_vid_codec_param codec_param; 
    217             struct { 
    218                 pj_uint32_t     pjmedia_id; 
    219                 const char     *codec_id; 
    220             } codec_fmts[] =  
    221                 {{PJMEDIA_FORMAT_MJPEG, "mjpeg"}, 
    222                  {PJMEDIA_FORMAT_H263, "h263"}}; 
    223             const char *codec_id = NULL; 
    224  
    225  
    226             status = pjmedia_codec_ffmpeg_init(NULL, mem); 
    227             if (status != PJ_SUCCESS) 
    228                 return -20; 
    229  
    230             /* Lookup codec */ 
    231             for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) { 
    232                 if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) { 
    233                     codec_id = codec_fmts[i].codec_id; 
    234                     break; 
    235                 } 
    236             } 
    237             if (!codec_id) { 
    238                 rc = 242; goto on_return; 
    239             } 
    240             pj_cstr(&codec_id_st, codec_id); 
    241             status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, 
    242                                                              &codec_id_st,  
    243                                                              &info_cnt,  
    244                                                              &codec_info, 
    245                                                              NULL); 
    246             if (status != PJ_SUCCESS) { 
    247                 rc = 245; goto on_return; 
    248             } 
    249             status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
    250                                                              &codec_param); 
    251             if (status != PJ_SUCCESS) { 
    252                 rc = 246; goto on_return; 
    253             } 
    254  
    255             pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info); 
    256             for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) { 
    257                 for (k=0; k<rdr_info.fmt_cnt; ++k) { 
    258                     if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id) 
    259                     { 
    260                         param.vidparam.fmt.id = codec_info->dec_fmt_id[i]; 
    261                     } 
    262                 } 
    263             } 
    264  
    265             /* Open codec */ 
    266             status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info, 
    267                                                        &codec); 
    268             if (status != PJ_SUCCESS) { 
    269                 rc = 250; goto on_return; 
    270             } 
    271  
    272             status = codec->op->init(codec, pool); 
    273             if (status != PJ_SUCCESS) { 
    274                 rc = 251; goto on_return; 
    275             } 
    276  
    277             pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt); 
    278  
    279             status = codec->op->open(codec, &codec_param); 
    280             if (status != PJ_SUCCESS) { 
    281                 rc = 252; goto on_return; 
    282             } 
    283  
    284             /* Alloc encoding buffer */ 
    285             enc_buf_size =  codec_param.dec_fmt.det.vid.size.w * 
    286                             codec_param.dec_fmt.det.vid.size.h * 4 
    287                             + 16; /*< padding, just in case */ 
    288             enc_buf = pj_pool_alloc(pool,enc_buf_size); 
    289  
    290             /* Init codec port */ 
    291             pj_bzero(&codec_port, sizeof(codec_port)); 
    292             status = pjmedia_port_info_init2(&codec_port.info, &port_name, 
    293                                              0x1234, 
    294                                              PJMEDIA_DIR_ENCODING,  
    295                                              &codec_param.dec_fmt); 
    296             if (status != PJ_SUCCESS) { 
    297                 rc = 260; goto on_return; 
    298             } 
    299             pj_bzero(&codec_port_data, sizeof(codec_port_data)); 
    300             codec_port_data.codec = codec; 
    301             codec_port_data.src_port = vid_port; 
    302             codec_port_data.enc_buf = enc_buf; 
    303             codec_port_data.enc_buf_size = enc_buf_size; 
    304  
    305             codec_port.get_frame = &codec_get_frame; 
    306             codec_port.port_data.pdata = &codec_port_data; 
    307  
    308             if (vid_port->info.fmt.id == PJMEDIA_FORMAT_MJPEG) { 
    309                 pjmedia_conversion_param conv_param; 
    310  
    311                 status = pjmedia_libswscale_converter_init(NULL, pool); 
    312  
    313                 pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt); 
    314                 pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt); 
    315                 conv_param.dst.id = PJMEDIA_FORMAT_I420; 
    316                 param.vidparam.fmt.id = conv_param.dst.id; 
    317  
    318                 status = pjmedia_converter_create(NULL, pool, &conv_param, 
    319                                                   &codec_port_data.conv); 
    320                 if (status != PJ_SUCCESS) { 
    321                     rc = 270; goto on_return; 
    322                 } 
    323             } 
    324  
    325             status = pjmedia_vid_port_create(pool, &param, &renderer); 
    326             if (status != PJ_SUCCESS) { 
    327                 rc = 230; goto on_return; 
    328             } 
    329  
    330             status = pjmedia_vid_port_connect(renderer, &codec_port, 
    331                                               PJ_FALSE); 
    332         } else { 
    333             status = pjmedia_vid_port_create(pool, &param, &renderer); 
    334             if (status != PJ_SUCCESS) { 
    335                 rc = 230; goto on_return; 
    336             } 
    337  
    338             /* Connect avi port to renderer */ 
    339             status = pjmedia_vid_port_connect(renderer, vid_port, 
    340                                               PJ_FALSE); 
    341         } 
    342  
    343         if (status != PJ_SUCCESS) { 
    344             rc = 240; goto on_return; 
    345         } 
    346     } 
    347  
    348     aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams, 
    349                                                          0, 
    350                                                          PJMEDIA_TYPE_AUDIO); 
    351     aud_port = pjmedia_avi_stream_get_port(aud_stream); 
    352  
    353     if (aud_port) { 
    354         status = pjmedia_aud_dev_default_param( 
    355                      PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV, 
    356                      &aparam); 
    357         if (status != PJ_SUCCESS) { 
    358             rc = 310; goto on_return; 
    359         } 
    360  
    361         aparam.dir = PJMEDIA_DIR_PLAYBACK; 
    362         afd = pjmedia_format_get_audio_format_detail(&aud_port->info.fmt, 
    363                                                      PJ_TRUE); 
    364         aparam.clock_rate = afd->clock_rate; 
    365         aparam.channel_count = afd->channel_count; 
    366         aparam.bits_per_sample = afd->bits_per_sample; 
    367         aparam.samples_per_frame = afd->frame_time_usec * aparam.clock_rate * 
    368                                    aparam.channel_count / 1000000; 
    369  
    370         status = pjmedia_aud_stream_create(&aparam, NULL, &avi_play_cb, 
    371                                            aud_port, 
    372                                            &strm); 
    373         if (status != PJ_SUCCESS) { 
    374             rc = 320; goto on_return; 
    375         } 
    376  
    377         /* Start audio streaming.. */ 
    378         status = pjmedia_aud_stream_start(strm); 
    379         if (status != PJ_SUCCESS) { 
    380             rc = 330; goto on_return; 
    381         } 
    382     } 
    383  
    384     if (vid_port) { 
    385         pjmedia_vid_cb cb; 
    386  
    387         pj_bzero(&cb, sizeof(cb)); 
    388         cb.on_event_cb = avi_event_cb; 
    389         avi_port.aud_stream = strm; 
    390         avi_port.vid_port = renderer; 
    391         avi_port.is_running = PJ_TRUE; 
    392         pjmedia_vid_port_set_cb(renderer, &cb, &avi_port); 
    393  
    394         /* Start video streaming.. */ 
    395         status = pjmedia_vid_port_start(renderer); 
    396         if (status != PJ_SUCCESS) { 
    397             rc = 270; goto on_return; 
    398         } 
    399     } 
    400  
    401 #if VID_DEV_TEST_MAC_OS 
    402     CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); 
    403 #endif 
    404      
    405     pj_thread_sleep(150000); 
    406  
    407 on_return: 
    408     if (strm) { 
    409         pjmedia_aud_stream_stop(strm); 
    410         pjmedia_aud_stream_destroy(strm); 
    411     } 
    412     if (renderer) 
    413         pjmedia_vid_port_destroy(renderer); 
    414     if (vid_port) 
    415         pjmedia_port_destroy(vid_port); 
    416     if (codec) { 
    417         codec->op->close(codec); 
    418         pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec); 
    419     } 
    420  
    421     return rc; 
    42272} 
    42373 
     
    42777    pjmedia_vid_port_param param; 
    42878    pjmedia_video_format_detail *vfd; 
     79    pjmedia_vid_cb cb; 
    42980    pj_status_t status; 
    430     int rc = 0; 
     81    int rc = 0, i; 
    43182 
    43283    PJ_LOG(3, (THIS_FILE, "  loopback test")); 
     
    43788    status = pjmedia_vid_dev_default_param(pool, 
    43889                                           PJMEDIA_VID_DEFAULT_CAPTURE_DEV, 
    439 //                                           3, /* Hard-coded capture device */ 
    44090                                           &param.vidparam); 
    44191    if (status != PJ_SUCCESS) { 
     
    463113    param.vidparam.dir = PJMEDIA_DIR_RENDER; 
    464114    param.vidparam.rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV; 
    465 //    param.vidparam.rend_id = 6; /* Hard-coded render device */ 
    466115    param.vidparam.disp_size = vfd->size; 
    467116 
     
    471120    } 
    472121 
     122    pj_bzero(&cb, sizeof(cb)); 
     123    cb.on_event_cb = vid_event_cb; 
     124    pjmedia_vid_port_set_cb(renderer, &cb, NULL); 
     125 
    473126    /* Connect capture to renderer */ 
    474     status = pjmedia_vid_port_connect(capture, 
    475                                       pjmedia_vid_port_get_passive_port(renderer), 
    476                                       PJ_FALSE); 
     127    status = pjmedia_vid_port_connect( 
     128                 capture, 
     129                 pjmedia_vid_port_get_passive_port(renderer), 
     130                 PJ_FALSE); 
    477131    if (status != PJ_SUCCESS) { 
    478132        rc = 140; goto on_return; 
     
    489143    } 
    490144 
    491 #if VID_DEV_TEST_MAC_OS 
    492     CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); 
    493 #endif 
    494      
    495145    /* Sleep while the webcam is being displayed... */ 
    496     pj_thread_sleep(20000); 
     146    for (i = 0; i < 50 && (!is_quitting); i++) { 
     147#if VID_DEV_TEST_MAC_OS 
     148        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); 
     149#endif 
     150        pj_thread_sleep(100); 
     151    } 
    497152 
    498153on_return: 
     
    526181        return -10; 
    527182 
    528     status = pjmedia_aud_subsys_init(mem); 
    529     if (status != PJ_SUCCESS) { 
    530         return -20; 
    531     } 
    532  
    533183    rc = enum_devs(); 
    534184    if (rc != 0) 
    535185        goto on_return; 
    536186 
    537     rc = aviplay_test(pool); 
    538     //if (rc != 0) 
    539     //    goto on_return; 
    540     // Ignore error 
    541     rc = 0; 
    542  
    543187    rc = loopback_test(pool); 
    544188    if (rc != 0) 
     
    546190 
    547191on_return: 
    548     pjmedia_aud_subsys_shutdown(); 
    549192    pjmedia_vid_subsys_shutdown(); 
    550193    pj_pool_release(pool); 
     
    556199    return rc; 
    557200} 
    558  
    559  
Note: See TracChangeset for help on using the changeset viewer.