Changeset 4836
- Timestamp:
- May 6, 2014 12:55:49 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-videodev/ios_dev.m
r4834 r4836 46 46 static ios_fmt_info ios_fmts[] = 47 47 { 48 { PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA } 48 { PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA }, 49 { PJMEDIA_FORMAT_I420, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange } 49 50 }; 50 51 … … 87 88 88 89 pjmedia_rect_size size; 89 pj_uint8_t bpp;90 90 unsigned bytes_per_row; 91 unsigned frame_size; 91 unsigned frame_size; /**< Frame size (bytes)*/ 92 pj_bool_t is_planar; 92 93 93 94 AVCaptureSession *cap_session; … … 95 96 AVCaptureVideoDataOutput *video_output; 96 97 VOutDelegate *vout_delegate; 98 void *capture_buf; 97 99 98 100 void *render_buf; … … 210 212 qdi->info.dir = PJMEDIA_DIR_RENDER; 211 213 qdi->info.has_callback = PJ_FALSE; 212 qdi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;213 214 214 215 /* Init input device */ … … 230 231 qdi = &qf->dev_info[qf->dev_count++]; 231 232 pj_bzero(qdi, sizeof(*qdi)); 232 pj_ansi_strncpy(qdi->info.name, [ [device localizedName]UTF8String],233 pj_ansi_strncpy(qdi->info.name, [device.localizedName UTF8String], 233 234 sizeof(qdi->info.name)); 234 235 pj_ansi_strncpy(qdi->info.driver, "iOS", sizeof(qdi->info.driver)); … … 236 237 qdi->info.has_callback = PJ_TRUE; 237 238 qdi->info.caps = PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW | 238 PJMEDIA_VID_DEV_CAP_SWITCH | 239 PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 239 PJMEDIA_VID_DEV_CAP_SWITCH; 240 240 qdi->dev = device; 241 241 } … … 252 252 for (i = 0; i < qf->dev_count; i++) { 253 253 qdi = &qf->dev_info[i]; 254 qdi->info.fmt_cnt = PJ_ARRAY_SIZE(ios_fmts);255 254 qdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT | 255 PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW | 256 256 PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE | 257 257 PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION | … … 260 260 261 261 for (l = 0; l < PJ_ARRAY_SIZE(ios_fmts); l++) { 262 pjmedia_format *fmt = &qdi->info.fmt[l]; 262 pjmedia_format *fmt; 263 264 /* Simple renderer UIView only supports BGRA */ 265 if (qdi->info.dir == PJMEDIA_DIR_RENDER && 266 ios_fmts[l].pjmedia_format != PJMEDIA_FORMAT_BGRA) 267 { 268 continue; 269 } 270 271 fmt = &qdi->info.fmt[qdi->info.fmt_cnt++]; 263 272 pjmedia_format_init_video(fmt, 264 273 ios_fmts[l].pjmedia_format, … … 378 387 fromConnection:(AVCaptureConnection *)connection 379 388 { 380 pjmedia_frame frame ;381 CVImageBufferRef im ageBuffer;389 pjmedia_frame frame = {0}; 390 CVImageBufferRef img; 382 391 383 392 if (!sampleBuffer) … … 385 394 386 395 /* Get a CMSampleBuffer's Core Video image buffer for the media data */ 387 im ageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);396 img = CMSampleBufferGetImageBuffer(sampleBuffer); 388 397 389 398 /* Lock the base address of the pixel buffer */ 390 CVPixelBufferLockBaseAddress(im ageBuffer, kCVPixelBufferLock_ReadOnly);399 CVPixelBufferLockBaseAddress(img, kCVPixelBufferLock_ReadOnly); 391 400 392 401 frame.type = PJMEDIA_FRAME_TYPE_VIDEO; 393 frame.buf = CVPixelBufferGetBaseAddress(imageBuffer);394 402 frame.size = stream->frame_size; 395 frame.bit_info = 0;396 403 frame.timestamp.u64 = stream->frame_ts.u64; 404 405 if (stream->is_planar && stream->capture_buf) { 406 if (stream->param.fmt.id == PJMEDIA_FORMAT_I420) { 407 /* kCVPixelFormatType_420YpCbCr8BiPlanar* is NV12 */ 408 pj_uint8_t *p, *p_end, *Y, *U, *V; 409 pj_size_t p_len; 410 411 p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 0); 412 p_len = stream->size.w * stream->size.h; 413 Y = (pj_uint8_t*)stream->capture_buf; 414 U = Y + p_len; 415 V = U + p_len/4; 416 pj_memcpy(Y, p, p_len); 417 418 p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 1); 419 p_len >>= 1; 420 p_end = p + p_len; 421 while (p < p_end) { 422 *U++ = *p++; 423 *V++ = *p++; 424 } 425 426 frame.buf = stream->capture_buf; 427 } 428 } else { 429 frame.buf = CVPixelBufferGetBaseAddress(img); 430 } 397 431 398 432 if (stream->vid_cb.capture_cb) { … … 411 445 412 446 /* Unlock the pixel buffer */ 413 CVPixelBufferUnlockBaseAddress(im ageBuffer, kCVPixelBufferLock_ReadOnly);447 CVPixelBufferUnlockBaseAddress(img, kCVPixelBufferLock_ReadOnly); 414 448 } 415 449 @end … … 508 542 vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 509 543 pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size)); 510 strm->bpp = vfi->bpp; 511 strm->bytes_per_row = strm->size.w * strm->bpp / 8; 544 strm->bytes_per_row = strm->size.w * vfi->bpp / 8; 512 545 strm->frame_size = strm->bytes_per_row * strm->size.h; 513 546 strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1); 547 strm->is_planar = vfi->plane_cnt > 1; 514 548 515 549 if (param->dir & PJMEDIA_DIR_CAPTURE) { … … 526 560 vfd->size.h = 288; 527 561 strm->size = vfd->size; 528 strm->bytes_per_row = strm->size.w * strm->bpp / 8;562 strm->bytes_per_row = strm->size.w * vfi->bpp / 8; 529 563 strm->frame_size = strm->bytes_per_row * strm->size.h; 530 564 … … 578 612 kCVPixelBufferPixelFormatTypeKey, nil]; 579 613 614 /* Prepare capture buffer if it's planar format */ 615 if (strm->is_planar) 616 strm->capture_buf = pj_pool_alloc(strm->pool, strm->frame_size); 617 580 618 /* Native preview */ 581 619 if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) { … … 677 715 ios_init_view(strm); 678 716 717 CALayer *view_layer = strm->render_view.layer; 718 CGRect r = strm->render_view.bounds; 719 679 720 /* Preview layer instantiation should be in main thread! */ 680 721 dispatch_async(dispatch_get_main_queue(), ^{ 681 722 /* Create preview layer */ 682 AVCaptureVideoPreviewLayer *previewLayer = 683 [AVCaptureVideoPreviewLayer layerWithSession:strm->cap_session]; 723 AVCaptureVideoPreviewLayer *prev_layer = 724 [AVCaptureVideoPreviewLayer 725 layerWithSession:strm->cap_session]; 684 726 685 727 /* Attach preview layer to a UIView */ 686 CGRect r = strm->render_view.bounds;687 prev iewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;688 previewLayer.frame = r;689 [[strm->render_view layer] addSublayer:previewLayer];728 prev_layer.videoGravity = AVLayerVideoGravityResizeAspectFill; 729 prev_layer.frame = r; 730 [view_layer addSublayer:prev_layer]; 731 PJ_LOG(4, (THIS_FILE, "Native preview initialized")); 690 732 }); 691 692 NSLog(@"Native preview initialized.");693 733 694 734 return PJ_SUCCESS; … … 721 761 /* Ok, let's do the switch */ 722 762 AVCaptureDeviceInput *cur_dev_input = strm->dev_input; 723 //[AVCaptureDeviceInput724 // deviceInputWithDevice:di[strm->param.cap_id].dev725 // error:&error];726 763 AVCaptureDeviceInput *new_dev_input = 727 764 [AVCaptureDeviceInput … … 750 787 return PJMEDIA_EVID_BADFORMAT; 751 788 752 vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(), 753 fmt->id); 789 vfi = pjmedia_get_video_format_info( 790 pjmedia_video_format_mgr_instance(), 791 fmt->id); 754 792 if (!vfi) 755 793 return PJMEDIA_EVID_BADFORMAT; … … 759 797 vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE); 760 798 pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size)); 761 strm->bytes_per_row = strm->size.w * strm->bpp / 8;799 strm->bytes_per_row = strm->size.w * vfi->bpp / 8; 762 800 strm->frame_size = strm->bytes_per_row * strm->size.h; 763 801 if (strm->render_buf_size < strm->frame_size) { 802 /* Realloc only when needed */ 764 803 strm->render_buf = pj_pool_alloc(strm->pool, strm->frame_size); 765 804 strm->render_buf_size = strm->frame_size; 766 805 CGDataProviderRelease(strm->render_data_provider); 767 806 strm->render_data_provider = CGDataProviderCreateWithData(NULL, 768 strm->render_buf, strm->frame_size, 807 strm->render_buf, 808 strm->frame_size, 769 809 NULL); 770 810 } … … 777 817 UIView *view = (UIView *)pval; 778 818 strm->param.window.info.ios.window = (void *)pval; 779 dispatch_async(dispatch_get_main_queue(), 780 ^{[view addSubview:strm->render_view];}); 819 dispatch_async(dispatch_get_main_queue(), ^{ 820 [view addSubview:strm->render_view]; 821 }); 781 822 return PJ_SUCCESS; 782 823 }
Note: See TracChangeset
for help on using the changeset viewer.