Changeset 65429 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jan 24, 2017 3:35:58 PM (8 years ago)
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
r65416 r65429 543 543 */ 544 544 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, 545 PPDMAUDIOSTREAM pStream, const void *pvBuf 2, uint32_t cbBuf2,545 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 546 546 uint32_t *pcbWritten) 547 547 { 548 RT_NOREF2(pvBuf2, cbBuf2);549 550 548 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 551 549 AssertPtrReturn(pStream, VERR_INVALID_POINTER); … … 555 553 RT_NOREF(pThis); 556 554 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 555 556 RT_NOREF(pvBuf, cbBuf); 557 557 558 558 uint32_t csLive = AudioMixBufUsed(&pStream->MixBuf); … … 578 578 AssertPtr(pCircBuf); 579 579 580 void *pv Buf;581 size_t cb Buf;580 void *pvCircBuf; 581 size_t cbCircBuf; 582 582 583 583 /* … … 586 586 while (RTCircBufFree(pCircBuf)) 587 587 { 588 RTCircBufAcquireWriteBlock(pCircBuf, RTCircBufFree(pCircBuf), &pv Buf, &cbBuf);588 RTCircBufAcquireWriteBlock(pCircBuf, RTCircBufFree(pCircBuf), &pvCircBuf, &cbCircBuf); 589 589 590 590 uint32_t cbRead = 0; 591 591 592 if (cb Buf)592 if (cbCircBuf) 593 593 { 594 594 uint32_t csRead = 0; 595 rc = AudioMixBufReadCirc(&pStream->MixBuf, pv Buf, cbBuf, &csRead);595 rc = AudioMixBufReadCirc(&pStream->MixBuf, pvCircBuf, cbCircBuf, &csRead); 596 596 if ( RT_SUCCESS(rc) 597 597 && csRead) … … 630 630 while (cbSrc < cbFrame) 631 631 { 632 RTCircBufAcquireReadBlock(pCircBuf, cbFrame - cbSrc, &pv Buf, &cbBuf);633 634 if (cb Buf)632 RTCircBufAcquireReadBlock(pCircBuf, cbFrame - cbSrc, &pvCircBuf, &cbCircBuf); 633 634 if (cbCircBuf) 635 635 { 636 memcpy(&abSrc[cbSrc], pv Buf, cbBuf);637 638 cbSrc += cb Buf;636 memcpy(&abSrc[cbSrc], pvCircBuf, cbCircBuf); 637 638 cbSrc += cbCircBuf; 639 639 Assert(cbSrc <= sizeof(abSrc)); 640 640 } 641 641 642 RTCircBufReleaseReadBlock(pCircBuf, cb Buf);643 644 if (!cb Buf)642 RTCircBufReleaseReadBlock(pCircBuf, cbCircBuf); 643 644 if (!cbCircBuf) 645 645 break; 646 646 } -
trunk/src/VBox/Main/src-client/VideoRec.cpp
r65426 r65429 127 127 uint64_t uCurTimeStampMs; 128 128 129 /** Whether the RGB buffer is filled or not. */ 130 bool fHasVideoData; 131 129 132 struct 130 133 { … … 137 140 /** Y resolution of the last encoded frame. */ 138 141 uint32_t uSrcLastHeight; 139 /** Current frame number. */ 140 uint64_t cFrame; 141 /** RGB buffer containing the most recent frame of the framebuffer. */ 142 /** RGB buffer containing the most recent frame of Main's framebuffer. */ 142 143 uint8_t *pu8RgbBuf; 143 144 /** YUV buffer the encode function fetches the frame from. */ 144 145 uint8_t *pu8YuvBuf; 145 /** Whether the RGB buffer is filled or not. */146 bool fRgbFilled;147 146 /** Pixel format of the current frame. */ 148 147 uint32_t uPixelFormat; 149 /** Minimal delay between two frames. */150 uint32_t uDelay ;148 /** Minimal delay (in ms) between two frames. */ 149 uint32_t uDelayMs; 151 150 /** Encoder deadline. */ 152 151 unsigned int uEncoderDeadline; 153 152 } Video; 154 155 153 } VIDEORECSTREAM, *PVIDEORECSTREAM; 156 154 … … 177 175 /** Vector of current video recording stream contexts. */ 178 176 VideoRecStreams vecStreams; 177 #ifdef VBOX_WITH_AUDIO_VIDEOREC 178 bool fHasAudioData; 179 struct 180 { 181 uint8_t buf[_64K]; 182 } Audio; 183 #endif 179 184 } VIDEORECCONTEXT, *PVIDEORECCONTEXT; 180 185 … … 461 466 break; 462 467 468 #ifdef VBOX_WITH_AUDIO_VIDEOREC 469 const bool fHasAudioData = ASMAtomicReadBool(&pCtx->fHasAudioData); 470 #endif 471 /** @todo r=andy This is inefficient -- as we already wake up this thread 472 * for every screen from Main, we here go again (on every wake up) through 473 * all screens. */ 463 474 for (VideoRecStreams::iterator it = pCtx->vecStreams.begin(); it != pCtx->vecStreams.end(); it++) 464 475 { 465 476 PVIDEORECSTREAM pStream = (*it); 466 477 467 if ( pStream->fEnabled 468 && ASMAtomicReadBool(&pStream->Video.fRgbFilled)) 478 if (!pStream->fEnabled) 479 continue; 480 481 if (ASMAtomicReadBool(&pStream->fHasVideoData)) 469 482 { 470 483 rc = videoRecRGBToYUV(pStream); 471 484 472 ASMAtomicWriteBool(&pStream-> Video.fRgbFilled, false);485 ASMAtomicWriteBool(&pStream->fHasVideoData, false); 473 486 474 487 if (RT_SUCCESS(rc)) … … 485 498 } 486 499 } 487 } 500 501 #ifdef VBOX_WITH_AUDIO_VIDEOREC 502 /* Each (enabled) screen has to get the audio data. */ 503 if (fHasAudioData) 504 { 505 WebMWriter::BlockData_Opus blockData = { pCtx->Audio.buf, }; 506 rc = pStream->pEBML->WriteBlock(pStream->uTrackAudio, &blockData, sizeof(blockData)); 507 } 508 #endif 509 } /* for */ 510 511 #ifdef VBOX_WITH_AUDIO_VIDEOREC 512 ASMAtomicWriteBool(&pCtx->fHasAudioData, false); 513 #endif 488 514 } 489 515 … … 650 676 * Retrieves a specific recording stream of a recording context. 651 677 * 652 * @returns Pointer to recording if found, or NULL if not found.653 * @param 654 * @param 678 * @returns Pointer to recording stream if found, or NULL if not found. 679 * @param pCtx Recording context to look up stream for. 680 * @param uScreen Screen number of recording stream to look up. 655 681 */ 656 682 DECLINLINE(PVIDEORECSTREAM) videoRecStreamGet(PVIDEORECCONTEXT pCtx, uint32_t uScreen) … … 801 827 } 802 828 803 pStream->Video.uDelay = 1000 / uFPS;829 pStream->Video.uDelayMs = 1000 / uFPS; 804 830 805 831 if (fHasVideoTrack) … … 863 889 pStream->fEnabled = true; 864 890 865 866 867 891 return VINF_SUCCESS; 868 892 } … … 889 913 * @param pCtx Pointer to video recording context. 890 914 * @param uScreen Screen ID. 891 * @param u 64TimeStampMsCurrent time stamp (in ms).892 */ 893 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u 64TimeStampMs)915 * @param uTimeStampMs Current time stamp (in ms). 916 */ 917 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs) 894 918 { 895 919 uint32_t enmState = ASMAtomicReadU32(&g_enmState); … … 904 928 } 905 929 906 if (u 64TimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelay)930 if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelayMs) 907 931 return false; 908 932 909 if (ASMAtomicReadBool(&pStream-> Video.fRgbFilled))933 if (ASMAtomicReadBool(&pStream->fHasVideoData)) 910 934 return false; 911 935 … … 971 995 &pStream->Codec.VPX.RawImage, 972 996 pts /* Time stamp */, 973 pStream->Video.uDelay /* How long to show this frame */,997 pStream->Video.uDelayMs /* How long to show this frame */, 974 998 0 /* Flags */, 975 999 pStream->Video.uEncoderDeadline /* Quality setting */); … … 1003 1027 } 1004 1028 } 1005 1006 pStream->Video.cFrame++;1007 1029 #else 1008 1030 RT_NOREF(pStream); … … 1016 1038 * 1017 1039 * @returns IPRT status code. 1018 * @param pStr m Strm.1040 * @param pStream Recording stream to convert RGB to YUV video frame buffer for. 1019 1041 */ 1020 1042 static int videoRecRGBToYUV(PVIDEORECSTREAM pStream) … … 1055 1077 * Sends an audio frame to the video encoding thread. 1056 1078 * 1079 * @thread EMT 1080 * 1057 1081 * @returns IPRT status code. 1058 1082 * @param pCtx Pointer to the video recording context. … … 1064 1088 { 1065 1089 RT_NOREF(pCtx, pvData, cbData, uTimestampMs); 1090 1091 /* To save time spent in EMT, do the required audio multiplexing in the encoding thread. 1092 * 1093 * The multiplexing is needed to supply all recorded (enabled) screens with the same 1094 * audio data at the same given point in time. 1095 */ 1096 1097 1066 1098 return VINF_SUCCESS; 1067 1099 } … … 1084 1116 * @param uSrcHeight Height of the video frame. 1085 1117 * @param puSrcData Pointer to video frame data. 1086 * @param u 64TimeStampMsTime stamp (in ms).1118 * @param uTimeStampMs Time stamp (in ms). 1087 1119 */ 1088 1120 int VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y, … … 1112 1144 if (!pStream->fEnabled) 1113 1145 { 1114 rc = VINF_TRY_AGAIN; /* not (yet) enabled */ 1115 break; 1116 } 1117 if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelay) 1118 { 1119 rc = VINF_TRY_AGAIN; /* respect maximum frames per second */ 1120 break; 1121 } 1122 if (ASMAtomicReadBool(&pStream->Video.fRgbFilled)) 1123 { 1124 rc = VERR_TRY_AGAIN; /* previous frame not yet encoded */ 1146 rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */ 1147 break; 1148 } 1149 1150 if (uTimeStampMs < pStream->uLastTimeStampMs + pStream->Video.uDelayMs) 1151 { 1152 rc = VINF_TRY_AGAIN; /* Respect maximum frames per second. */ 1153 break; 1154 } 1155 1156 if (ASMAtomicReadBool(&pStream->fHasVideoData)) 1157 { 1158 rc = VERR_TRY_AGAIN; /* Previous frame not yet encoded. */ 1125 1159 break; 1126 1160 } … … 1130 1164 int xDiff = ((int)pStream->Video.uDstWidth - (int)uSrcWidth) / 2; 1131 1165 uint32_t w = uSrcWidth; 1132 if ((int)w + xDiff + (int)x <= 0) /* nothing visible*/1166 if ((int)w + xDiff + (int)x <= 0) /* Nothing visible. */ 1133 1167 { 1134 1168 rc = VERR_INVALID_PARAMETER; … … 1148 1182 uint32_t h = uSrcHeight; 1149 1183 int yDiff = ((int)pStream->Video.uDstHeight - (int)uSrcHeight) / 2; 1150 if ((int)h + yDiff + (int)y <= 0) /* nothing visible*/1184 if ((int)h + yDiff + (int)y <= 0) /* Nothing visible. */ 1151 1185 { 1152 1186 rc = VERR_INVALID_PARAMETER; … … 1167 1201 || destY > pStream->Video.uDstHeight) 1168 1202 { 1169 rc = VERR_INVALID_PARAMETER; /* nothing visible*/1203 rc = VERR_INVALID_PARAMETER; /* Nothing visible. */ 1170 1204 break; 1171 1205 } … … 1219 1253 for (unsigned int i = 0; i < h; i++) 1220 1254 { 1221 /* Overflow check */1255 /* Overflow check. */ 1222 1256 Assert(offSrc + w * bpp <= uSrcHeight * uBytesPerLine); 1223 1257 Assert(offDst + w * bpp <= pStream->Video.uDstHeight * pStream->Video.uDstWidth * bpp); 1258 1224 1259 memcpy(pStream->Video.pu8RgbBuf + offDst, puSrcData + offSrc, w * bpp); 1260 1225 1261 offSrc += uBytesPerLine; 1226 1262 offDst += pStream->Video.uDstWidth * bpp; … … 1229 1265 pStream->uCurTimeStampMs = uTimeStampMs; 1230 1266 1231 ASMAtomicWriteBool(&pStream-> Video.fRgbFilled, true);1267 ASMAtomicWriteBool(&pStream->fHasVideoData, true); 1232 1268 RTSemEventSignal(pCtx->WaitEvent); 1233 1269 -
trunk/src/VBox/Main/src-client/VideoRec.h
r65418 r65429 29 29 30 30 int VideoRecStreamInit(PVIDEORECCONTEXT pCtx, uint32_t uScreen, const char *pszFile, 31 uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uF ps,32 uint32_t uMaxTime , uint32_t uMaxFileSize, const char *pszOptions);31 uint32_t uWidth, uint32_t uHeight, uint32_t uRate, uint32_t uFPS, 32 uint32_t uMaxTimeS, uint32_t uMaxFileSizeMB, const char *pszOptions); 33 33 34 34 bool VideoRecIsEnabled(PVIDEORECCONTEXT pCtx); 35 35 int VideoRecSendAudioFrame(PVIDEORECCONTEXT pCtx, const void *pvData, size_t cbData, uint64_t uTimestampMs); 36 36 int VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen, 37 uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uB itsPerPixel,38 uint32_t uBytesPerLine, uint32_t u GuestWidth, uint32_t uGuestHeight,39 uint8_t *pu 8BufferAddress, uint64_t u64TimeStampMs);40 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u 64TimeStampMs);41 bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t u64TimeStampMs);37 uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, 38 uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight, 39 uint8_t *puSrcData, uint64_t uTimeStampMs); 40 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs); 41 bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t tsNowMs); 42 42 43 43 #endif /* !____H_VIDEOREC */
Note:
See TracChangeset
for help on using the changeset viewer.