vbox的更動 45950 路徑 trunk/src/VBox/Main/src-client/VideoRec.cpp
- 時間撮記:
- 2013-5-8 下午01:00:13 (12 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Main/src-client/VideoRec.cpp
r45941 r45950 37 37 #define DEFAULTCODEC (vpx_codec_vp8_cx()) 38 38 39 static int videoRecEncodeAndWrite(PVIDEOREC CONTEXT pVideoRecCtx);40 static int videoRecRGBToYUV(PVIDEOREC CONTEXT pVideoRecCtx);39 static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStrm); 40 static int videoRecRGBToYUV(PVIDEORECSTREAM pStrm); 41 41 42 42 /* encoding */ … … 52 52 }; 53 53 54 typedef struct VIDEOREC CONTEXT54 typedef struct VIDEORECSTREAM 55 55 { 56 56 /* container context */ 57 EbmlGlobal ebml;57 EbmlGlobal Ebml; 58 58 /* VPX codec context */ 59 59 vpx_codec_ctx_t VpxCodec; … … 76 76 /* VPX image context */ 77 77 vpx_image_t VpxRawImage; 78 /* semaphore */79 RTSEMEVENT WaitEvent;80 78 /* true if video recording is enabled */ 81 79 bool fEnabled; … … 94 92 /* time stamp of the current frame */ 95 93 uint64_t u64TimeStamp; 94 } VIDEORECSTREAM; 95 96 typedef struct VIDEORECCONTEXT 97 { 98 /* semaphore */ 99 RTSEMEVENT WaitEvent; 100 /* true if video recording is enabled */ 101 bool fEnabled; 102 /* worker thread */ 103 RTTHREAD Thread; 104 /* see VIDREC_xxx */ 105 uint32_t u32State; 106 /* number of stream contexts */ 107 uint32_t cScreens; 108 /* video recording stream contexts */ 109 VIDEORECSTREAM Strm[1]; 96 110 } VIDEORECCONTEXT; 97 111 … … 365 379 366 380 /** 367 * VideoRec utility function to create video recording context. 368 * 369 * @returns IPRT status code. 370 * @param ppVideoRecCtx video recording context 371 */ 372 int VideoRecContextCreate(PVIDEORECCONTEXT *ppVideoRecCtx) 373 { 374 PVIDEORECCONTEXT pVideoRecCtx = (PVIDEORECCONTEXT)RTMemAllocZ(sizeof(VIDEORECCONTEXT)); 375 *ppVideoRecCtx = pVideoRecCtx; 376 AssertReturn(pVideoRecCtx, VERR_NO_MEMORY); 377 378 pVideoRecCtx->ebml.last_pts_ms = -1; 379 return VINF_SUCCESS; 380 } 381 382 /** 383 * Worker thread. 381 * Worker thread for all streams. 384 382 * 385 383 * RGB/YUV conversion and encoding. 386 384 */ 387 DECLCALLBACK(int) VideoRecThread(RTTHREAD ThreadSelf, void *pvUser)388 { 389 PVIDEORECCONTEXT p VideoRecCtx = (PVIDEORECCONTEXT)pvUser;385 DECLCALLBACK(int) videoRecThread(RTTHREAD ThreadSelf, void *pvUser) 386 { 387 PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)pvUser; 390 388 for (;;) 391 389 { 392 int rc = RTSemEventWait(p VideoRecCtx->WaitEvent, RT_INDEFINITE_WAIT);390 int rc = RTSemEventWait(pCtx->WaitEvent, RT_INDEFINITE_WAIT); 393 391 AssertRCBreak(rc); 394 392 395 if (ASMAtomicReadU32(&p VideoRecCtx->u32State) == VIDREC_TERMINATING)393 if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_TERMINATING) 396 394 break; 397 else if (ASMAtomicReadBool(&pVideoRecCtx->fRgbFilled)) 398 { 399 rc = videoRecRGBToYUV(pVideoRecCtx); 400 ASMAtomicWriteBool(&pVideoRecCtx->fRgbFilled, false); 401 if (RT_SUCCESS(rc)) 402 rc = videoRecEncodeAndWrite(pVideoRecCtx); 403 if (RT_FAILURE(rc)) 404 LogRel(("Error %Rrc encoding video frame\n", rc)); 405 } 406 } 407 408 ASMAtomicWriteU32(&pVideoRecCtx->u32State, VIDREC_TERMINATED); 395 for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++) 396 { 397 PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen]; 398 if (ASMAtomicReadBool(&pStrm->fRgbFilled)) 399 { 400 rc = videoRecRGBToYUV(pStrm); 401 ASMAtomicWriteBool(&pStrm->fRgbFilled, false); 402 if (RT_SUCCESS(rc)) 403 rc = videoRecEncodeAndWrite(pStrm); 404 if (RT_FAILURE(rc)) 405 LogRel(("Error %Rrc encoding video frame\n", rc)); 406 } 407 } 408 } 409 410 ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATED); 409 411 RTThreadUserSignal(ThreadSelf); 410 412 return VINF_SUCCESS; … … 412 414 413 415 /** 416 * VideoRec utility function to create video recording context. 417 * 418 * @returns IPRT status code. 419 * @param ppCtx Video recording context 420 * @param cScreens Number of screens. 421 */ 422 int VideoRecContextCreate(PVIDEORECCONTEXT *ppCtx, uint32_t cScreens) 423 { 424 PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)RTMemAllocZ(RT_OFFSETOF(VIDEORECCONTEXT, Strm[cScreens])); 425 *ppCtx = pCtx; 426 AssertPtrReturn(pCtx, VERR_NO_MEMORY); 427 428 pCtx->cScreens = cScreens; 429 for (unsigned uScreen = 0; uScreen < cScreens; uScreen++) 430 pCtx->Strm[uScreen].Ebml.last_pts_ms = -1; 431 432 int rc = RTSemEventCreate(&pCtx->WaitEvent); 433 AssertRCReturn(rc, rc); 434 435 rc = RTThreadCreate(&pCtx->Thread, videoRecThread, (void*)pCtx, 0, 436 RTTHREADTYPE_MAIN_WORKER, 0, "VideoRec"); 437 AssertRCReturn(rc, rc); 438 439 return VINF_SUCCESS; 440 } 441 442 /** 414 443 * VideoRec utility function to initialize video recording context. 415 444 * 416 445 * @returns IPRT status code. 417 * @param pVideoRecCtx Pointer to video recording context to initialize Framebuffer width. 446 * @param pCtx Pointer to video recording context to initialize Framebuffer width. 447 * @param uScreeen Screen number. 418 448 * @param strFile File to save the recorded data 419 449 * @param uTargetWidth Width of the target image in the video recoriding file (movie) 420 450 * @param uTargetHeight Height of the target image in video recording file. 421 451 */ 422 int VideoRecContextInit(PVIDEORECCONTEXT pVideoRecCtx, const char *pszFile, 423 uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps) 424 { 425 pVideoRecCtx->uTargetWidth = uWidth; 426 pVideoRecCtx->uTargetHeight = uHeight; 427 pVideoRecCtx->pu8RgbBuf = (uint8_t *)RTMemAllocZ(uWidth * uHeight * 4); 428 AssertReturn(pVideoRecCtx->pu8RgbBuf, VERR_NO_MEMORY); 429 430 int rc = RTFileOpen(&pVideoRecCtx->ebml.file, pszFile, 452 int VideoRecStrmInit(PVIDEORECCONTEXT pCtx, uint32_t uScreen, const char *pszFile, 453 uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFps) 454 { 455 AssertPtrReturn(pCtx, VERR_INVALID_PARAMETER); 456 AssertReturn(uScreen < pCtx->cScreens, VERR_INVALID_PARAMETER); 457 458 PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen]; 459 pStrm->uTargetWidth = uWidth; 460 pStrm->uTargetHeight = uHeight; 461 pStrm->pu8RgbBuf = (uint8_t *)RTMemAllocZ(uWidth * uHeight * 4); 462 AssertReturn(pStrm->pu8RgbBuf, VERR_NO_MEMORY); 463 464 int rc = RTFileOpen(&pStrm->Ebml.file, pszFile, 431 465 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 432 466 if (RT_FAILURE(rc)) … … 436 470 } 437 471 438 vpx_codec_err_t rcv = vpx_codec_enc_config_default(DEFAULTCODEC, &p VideoRecCtx->VpxConfig, 0);472 vpx_codec_err_t rcv = vpx_codec_enc_config_default(DEFAULTCODEC, &pStrm->VpxConfig, 0); 439 473 if (rcv != VPX_CODEC_OK) 440 474 { … … 444 478 445 479 /* target bitrate in kilobits per second */ 446 p VideoRecCtx->VpxConfig.rc_target_bitrate = uRate;480 pStrm->VpxConfig.rc_target_bitrate = uRate; 447 481 /* frame width */ 448 p VideoRecCtx->VpxConfig.g_w = uWidth;482 pStrm->VpxConfig.g_w = uWidth; 449 483 /* frame height */ 450 p VideoRecCtx->VpxConfig.g_h = uHeight;484 pStrm->VpxConfig.g_h = uHeight; 451 485 /* 1ms per frame */ 452 p VideoRecCtx->VpxConfig.g_timebase.num = 1;453 p VideoRecCtx->VpxConfig.g_timebase.den = 1000;486 pStrm->VpxConfig.g_timebase.num = 1; 487 pStrm->VpxConfig.g_timebase.den = 1000; 454 488 /* disable multithreading */ 455 p VideoRecCtx->VpxConfig.g_threads = 0;456 p VideoRecCtx->uDelay = 1000 / uFps;489 pStrm->VpxConfig.g_threads = 0; 490 pStrm->uDelay = 1000 / uFps; 457 491 458 492 struct vpx_rational arg_framerate = {30, 1}; 459 rc = Ebml_WriteWebMFileHeader(&p VideoRecCtx->ebml, &pVideoRecCtx->VpxConfig, &arg_framerate);493 rc = Ebml_WriteWebMFileHeader(&pStrm->Ebml, &pStrm->VpxConfig, &arg_framerate); 460 494 AssertRCReturn(rc, rc); 461 495 462 496 /* Initialize codec */ 463 rcv = vpx_codec_enc_init(&pVideoRecCtx->VpxCodec, DEFAULTCODEC, 464 &pVideoRecCtx->VpxConfig, 0); 497 rcv = vpx_codec_enc_init(&pStrm->VpxCodec, DEFAULTCODEC, &pStrm->VpxConfig, 0); 465 498 if (rcv != VPX_CODEC_OK) 466 499 { … … 469 502 } 470 503 471 ASMAtomicWriteU32(&p VideoRecCtx->u32State, VIDREC_INITIALIZED);472 473 if (!vpx_img_alloc(&p VideoRecCtx->VpxRawImage, VPX_IMG_FMT_I420, uWidth, uHeight, 1))504 ASMAtomicWriteU32(&pStrm->u32State, VIDREC_INITIALIZED); 505 506 if (!vpx_img_alloc(&pStrm->VpxRawImage, VPX_IMG_FMT_I420, uWidth, uHeight, 1)) 474 507 { 475 508 LogFlow(("Failed to allocate image %dx%d", uWidth, uHeight)); 476 509 return VERR_NO_MEMORY; 477 510 } 478 pVideoRecCtx->pu8YuvBuf = pVideoRecCtx->VpxRawImage.planes[0]; 479 480 rc = RTSemEventCreate(&pVideoRecCtx->WaitEvent); 481 AssertRCReturn(rc, rc); 482 483 rc = RTThreadCreate(&pVideoRecCtx->Thread, VideoRecThread, 484 (void*)pVideoRecCtx, 0, 485 RTTHREADTYPE_MAIN_WORKER, 0, "VideoRec"); 486 AssertRCReturn(rc, rc); 487 488 pVideoRecCtx->fEnabled = true; 511 pStrm->pu8YuvBuf = pStrm->VpxRawImage.planes[0]; 512 513 pCtx->fEnabled = true; 489 514 return VINF_SUCCESS; 490 515 } … … 493 518 * VideoRec utility function to close the video recording context. 494 519 * 495 * @param p VideoRecCtx Pointer to video recording context.496 */ 497 void VideoRecContextClose(PVIDEORECCONTEXT p VideoRecCtx)498 { 499 if (ASMAtomicReadU32(&p VideoRecCtx->u32State) == VIDREC_UNINITIALIZED)520 * @param pCtx Pointer to video recording context. 521 */ 522 void VideoRecContextClose(PVIDEORECCONTEXT pCtx) 523 { 524 if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_UNINITIALIZED) 500 525 return; 501 526 502 if (pVideoRecCtx->ebml.file != NIL_RTFILE) 503 { 504 int rc = Ebml_WriteWebMFileFooter(&pVideoRecCtx->ebml, 0); 505 AssertRC(rc); 506 RTFileClose(pVideoRecCtx->ebml.file); 507 pVideoRecCtx->ebml.file = NIL_RTFILE; 508 } 509 if (pVideoRecCtx->ebml.cue_list) 510 { 511 RTMemFree(pVideoRecCtx->ebml.cue_list); 512 pVideoRecCtx->ebml.cue_list = NULL; 513 } 514 if (pVideoRecCtx->fEnabled) 515 { 516 ASMAtomicWriteU32(&pVideoRecCtx->u32State, VIDREC_TERMINATING); 517 RTSemEventSignal(pVideoRecCtx->WaitEvent); 518 RTThreadUserWait(pVideoRecCtx->Thread, 10000); 519 RTSemEventDestroy(pVideoRecCtx->WaitEvent); 520 vpx_img_free(&pVideoRecCtx->VpxRawImage); 521 vpx_codec_destroy(&pVideoRecCtx->VpxCodec); 522 RTMemFree(pVideoRecCtx->pu8RgbBuf); 523 pVideoRecCtx->pu8RgbBuf = NULL; 527 if (pCtx->fEnabled) 528 { 529 ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATING); 530 RTSemEventSignal(pCtx->WaitEvent); 531 RTThreadUserWait(pCtx->Thread, 10000); 532 RTSemEventDestroy(pCtx->WaitEvent); 533 } 534 535 for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++) 536 { 537 PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen]; 538 if (pStrm->Ebml.file != NIL_RTFILE) 539 { 540 int rc = Ebml_WriteWebMFileFooter(&pStrm->Ebml, 0); 541 AssertRC(rc); 542 RTFileClose(pStrm->Ebml.file); 543 pStrm->Ebml.file = NIL_RTFILE; 544 } 545 if (pStrm->Ebml.cue_list) 546 { 547 RTMemFree(pStrm->Ebml.cue_list); 548 pStrm->Ebml.cue_list = NULL; 549 } 550 vpx_img_free(&pStrm->VpxRawImage); 551 vpx_codec_destroy(&pStrm->VpxCodec); 552 RTMemFree(pStrm->pu8RgbBuf); 553 pStrm->pu8RgbBuf = NULL; 524 554 } 525 555 } … … 529 559 * 530 560 * @returns true if recording is enabled 531 * @param p VideoRecCtx Pointer to video recording context.532 */ 533 bool VideoRecIsEnabled(PVIDEORECCONTEXT p VideoRecCtx)534 { 535 if (!p VideoRecCtx)561 * @param pCtx Pointer to video recording context. 562 */ 563 bool VideoRecIsEnabled(PVIDEORECCONTEXT pCtx) 564 { 565 if (!pCtx) 536 566 return false; 537 567 538 return p VideoRecCtx->fEnabled;568 return pCtx->fEnabled; 539 569 } 540 570 … … 544 574 * 545 575 * @returns IPRT status code. 546 * @param p VideoRecCtx Pointer to video recording context.576 * @param pCtx Pointer to video recording context. 547 577 * @param uSourceWidth Width of the source image. 548 578 * @param uSourceHeight Height of the source image. 549 579 */ 550 static int videoRecEncodeAndWrite(PVIDEOREC CONTEXT pVideoRecCtx)580 static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStrm) 551 581 { 552 582 /* presentation time stamp */ 553 vpx_codec_pts_t pts = p VideoRecCtx->u64TimeStamp;554 vpx_codec_err_t rcv = vpx_codec_encode(&p VideoRecCtx->VpxCodec,555 &p VideoRecCtx->VpxRawImage,583 vpx_codec_pts_t pts = pStrm->u64TimeStamp; 584 vpx_codec_err_t rcv = vpx_codec_encode(&pStrm->VpxCodec, 585 &pStrm->VpxRawImage, 556 586 pts /* time stamp */, 557 587 10 /* how long to show this frame */, … … 568 598 for (;;) 569 599 { 570 const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(&p VideoRecCtx->VpxCodec, &iter);600 const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(&pStrm->VpxCodec, &iter); 571 601 if (!pkt) 572 602 break; … … 574 604 { 575 605 case VPX_CODEC_CX_FRAME_PKT: 576 rc = Ebml_WriteWebMBlock(&p VideoRecCtx->ebml, &pVideoRecCtx->VpxConfig, pkt);606 rc = Ebml_WriteWebMBlock(&pStrm->Ebml, &pStrm->VpxConfig, pkt); 577 607 break; 578 608 default: … … 582 612 } 583 613 584 p VideoRecCtx->cFrame++;614 pStrm->cFrame++; 585 615 return rc; 586 616 } … … 590 620 * 591 621 * @returns IPRT status code. 592 * @param p VideoRecCtx Pointer to video recording context.593 */ 594 static int videoRecRGBToYUV(PVIDEOREC CONTEXT pVideoRecCtx)595 { 596 switch (p VideoRecCtx->u32PixelFormat)622 * @param pCtx Pointer to video recording context. 623 */ 624 static int videoRecRGBToYUV(PVIDEORECSTREAM pStrm) 625 { 626 switch (pStrm->u32PixelFormat) 597 627 { 598 628 case VPX_IMG_FMT_RGB32: 599 629 LogFlow(("32 bit\n")); 600 if (!colorConvWriteYUV420p<ColorConvBGRA32Iter>(p VideoRecCtx->uTargetWidth,601 p VideoRecCtx->uTargetHeight,602 p VideoRecCtx->pu8YuvBuf,603 p VideoRecCtx->pu8RgbBuf))630 if (!colorConvWriteYUV420p<ColorConvBGRA32Iter>(pStrm->uTargetWidth, 631 pStrm->uTargetHeight, 632 pStrm->pu8YuvBuf, 633 pStrm->pu8RgbBuf)) 604 634 return VERR_GENERAL_FAILURE; 605 635 break; 606 636 case VPX_IMG_FMT_RGB24: 607 637 LogFlow(("24 bit\n")); 608 if (!colorConvWriteYUV420p<ColorConvBGR24Iter>(p VideoRecCtx->uTargetWidth,609 p VideoRecCtx->uTargetHeight,610 p VideoRecCtx->pu8YuvBuf,611 p VideoRecCtx->pu8RgbBuf))638 if (!colorConvWriteYUV420p<ColorConvBGR24Iter>(pStrm->uTargetWidth, 639 pStrm->uTargetHeight, 640 pStrm->pu8YuvBuf, 641 pStrm->pu8RgbBuf)) 612 642 return VERR_GENERAL_FAILURE; 613 643 break; 614 644 case VPX_IMG_FMT_RGB565: 615 645 LogFlow(("565 bit\n")); 616 if (!colorConvWriteYUV420p<ColorConvBGR565Iter>(p VideoRecCtx->uTargetWidth,617 p VideoRecCtx->uTargetHeight,618 p VideoRecCtx->pu8YuvBuf,619 p VideoRecCtx->pu8RgbBuf))646 if (!colorConvWriteYUV420p<ColorConvBGR565Iter>(pStrm->uTargetWidth, 647 pStrm->uTargetHeight, 648 pStrm->pu8YuvBuf, 649 pStrm->pu8RgbBuf)) 620 650 return VERR_GENERAL_FAILURE; 621 651 break; … … 631 661 * 632 662 * @returns IPRT status code. 633 * @param pVideoRecCtx Pointer to video recording context. 663 * @param pCtx Pointer to the video recording context. 664 * @param uScreen Screen number. 634 665 * @param x Starting x coordinate of the source buffer (Framebuffer). 635 666 * @param y Starting y coordinate of the source buffer (Framebuffer). … … 642 673 * @param u64TimeStamp Time stamp (milliseconds). 643 674 */ 644 int VideoRecCopyToIntBuf(PVIDEORECCONTEXT p VideoRecCtx, uint32_t x, uint32_t y,675 int VideoRecCopyToIntBuf(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y, 645 676 uint32_t uPixelFormat, uint32_t uBitsPerPixel, uint32_t uBytesPerLine, 646 677 uint32_t uSourceWidth, uint32_t uSourceHeight, uint8_t *pu8BufAddr, … … 650 681 AssertReturn(uSourceWidth, VERR_INVALID_PARAMETER); 651 682 AssertReturn(uSourceHeight, VERR_INVALID_PARAMETER); 652 653 if (u64TimeStamp < pVideoRecCtx->u64LastTimeStamp + pVideoRecCtx->uDelay) 683 AssertReturn(uScreen < pCtx->cScreens, VERR_INVALID_PARAMETER); 684 685 PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen]; 686 687 if (u64TimeStamp < pStrm->u64LastTimeStamp + pStrm->uDelay) 654 688 return VINF_TRY_AGAIN; 655 p VideoRecCtx->u64LastTimeStamp = u64TimeStamp;656 657 if (ASMAtomicReadBool(&p VideoRecCtx->fRgbFilled))689 pStrm->u64LastTimeStamp = u64TimeStamp; 690 691 if (ASMAtomicReadBool(&pStrm->fRgbFilled)) 658 692 return VERR_TRY_AGAIN; 659 693 660 int xDiff = ((int)p VideoRecCtx->uTargetWidth - (int)uSourceWidth) / 2;694 int xDiff = ((int)pStrm->uTargetWidth - (int)uSourceWidth) / 2; 661 695 uint32_t w = uSourceWidth; 662 696 if ((int)w + xDiff + (int)x <= 0) /* nothing visible */ … … 674 708 675 709 uint32_t h = uSourceHeight; 676 int yDiff = ((int)p VideoRecCtx->uTargetHeight - (int)uSourceHeight) / 2;710 int yDiff = ((int)pStrm->uTargetHeight - (int)uSourceHeight) / 2; 677 711 if ((int)h + yDiff + (int)y <= 0) /* nothing visible */ 678 712 return VERR_INVALID_PARAMETER; … … 688 722 destY = y + yDiff; 689 723 690 if ( destX > p VideoRecCtx->uTargetWidth691 || destY > p VideoRecCtx->uTargetHeight)724 if ( destX > pStrm->uTargetWidth 725 || destY > pStrm->uTargetHeight) 692 726 return VERR_INVALID_PARAMETER; /* nothing visible */ 693 727 694 if (destX + w > p VideoRecCtx->uTargetWidth)695 w = p VideoRecCtx->uTargetWidth - destX;696 697 if (destY + h > p VideoRecCtx->uTargetHeight)698 h = p VideoRecCtx->uTargetHeight - destY;728 if (destX + w > pStrm->uTargetWidth) 729 w = pStrm->uTargetWidth - destX; 730 731 if (destY + h > pStrm->uTargetHeight) 732 h = pStrm->uTargetHeight - destY; 699 733 700 734 /* Calculate bytes per pixel */ … … 705 739 { 706 740 case 32: 707 p VideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB32;741 pStrm->u32PixelFormat = VPX_IMG_FMT_RGB32; 708 742 bpp = 4; 709 743 break; 710 744 case 24: 711 p VideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB24;745 pStrm->u32PixelFormat = VPX_IMG_FMT_RGB24; 712 746 bpp = 3; 713 747 break; 714 748 case 16: 715 p VideoRecCtx->u32PixelFormat = VPX_IMG_FMT_RGB565;749 pStrm->u32PixelFormat = VPX_IMG_FMT_RGB565; 716 750 bpp = 2; 717 751 break; … … 726 760 /* One of the dimensions of the current frame is smaller than before so 727 761 * clear the entire buffer to prevent artifacts from the previous frame */ 728 if ( uSourceWidth < pVideoRecCtx->uLastSourceWidth 729 || uSourceHeight < pVideoRecCtx->uLastSourceHeight) 730 { 731 memset(pVideoRecCtx->pu8RgbBuf, 0, 732 pVideoRecCtx->uTargetWidth * pVideoRecCtx->uTargetHeight * 4); 733 } 734 pVideoRecCtx->uLastSourceWidth = uSourceWidth; 735 pVideoRecCtx->uLastSourceHeight = uSourceHeight; 762 if ( uSourceWidth < pStrm->uLastSourceWidth 763 || uSourceHeight < pStrm->uLastSourceHeight) 764 memset(pStrm->pu8RgbBuf, 0, pStrm->uTargetWidth * pStrm->uTargetHeight * 4); 765 766 pStrm->uLastSourceWidth = uSourceWidth; 767 pStrm->uLastSourceHeight = uSourceHeight; 736 768 737 769 /* Calculate start offset in source and destination buffers */ 738 770 uint32_t offSrc = y * uBytesPerLine + x * bpp; 739 uint32_t offDst = (destY * p VideoRecCtx->uTargetWidth + destX) * bpp;771 uint32_t offDst = (destY * pStrm->uTargetWidth + destX) * bpp; 740 772 /* do the copy */ 741 773 for (unsigned int i = 0; i < h; i++) … … 743 775 /* Overflow check */ 744 776 Assert(offSrc + w * bpp <= uSourceHeight * uBytesPerLine); 745 Assert(offDst + w * bpp <= p VideoRecCtx->uTargetHeight * pVideoRecCtx->uTargetWidth * bpp);746 memcpy(p VideoRecCtx->pu8RgbBuf + offDst, pu8BufAddr + offSrc, w * bpp);777 Assert(offDst + w * bpp <= pStrm->uTargetHeight * pStrm->uTargetWidth * bpp); 778 memcpy(pStrm->pu8RgbBuf + offDst, pu8BufAddr + offSrc, w * bpp); 747 779 offSrc += uBytesPerLine; 748 offDst += p VideoRecCtx->uTargetWidth * bpp;749 } 750 751 p VideoRecCtx->u64TimeStamp = u64TimeStamp;752 753 ASMAtomicWriteBool(&p VideoRecCtx->fRgbFilled, true);754 RTSemEventSignal(p VideoRecCtx->WaitEvent);780 offDst += pStrm->uTargetWidth * bpp; 781 } 782 783 pStrm->u64TimeStamp = u64TimeStamp; 784 785 ASMAtomicWriteBool(&pStrm->fRgbFilled, true); 786 RTSemEventSignal(pCtx->WaitEvent); 755 787 756 788 return VINF_SUCCESS;
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器