Changeset 65330 in vbox
- Timestamp:
- Jan 16, 2017 1:38:36 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 112908
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
r65281 r65330 96 96 AVRECCODEC Codec; 97 97 /** (Audio) frame buffer. */ 98 PRTCIRCBUF pCircBuf; 98 99 uint8_t *pvFrameBuf; 99 100 size_t cbFrameBufSize; … … 121 122 * See the AVRECMODE enumeration for more information. */ 122 123 WebMWriter *pEBML; 124 /** Track number for audio data. */ 125 uint8_t uTrack; 123 126 } DRVAUDIOVIDEOREC, *PDRVAUDIOVIDEOREC; 124 127 … … 141 144 142 145 #ifdef VBOX_WITH_LIBOPUS 146 RTCircBufCreate(&pStreamOut->pCircBuf, _4K); 147 143 148 rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamOut->Props); 144 149 if (RT_SUCCESS(rc)) 145 150 { 146 size_t cbFrameBuf = sizeof(uint8_t) * _ 8K; /** @todo Make this configurable */151 size_t cbFrameBuf = sizeof(uint8_t) * _4K; /** @todo Make this configurable */ 147 152 148 153 pStreamOut->pvFrameBuf = (uint8_t *)RTMemAlloc(cbFrameBuf); … … 235 240 WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None); 236 241 if (RT_SUCCESS(rc)) 237 rc = pThis->pEBML->AddAudioTrack(44100, 2, 16 );242 rc = pThis->pEBML->AddAudioTrack(44100, 2, 16, &pThis->uTrack); 238 243 break; 239 244 } … … 285 290 */ 286 291 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, 287 PPDMAUDIOSTREAM pStream, const void *pvBuf , uint32_t cbBuf,292 PPDMAUDIOSTREAM pStream, const void *pvBuf2, uint32_t cbBuf2, 288 293 uint32_t *pcbWritten) 289 294 { 290 RT_NOREF2(pvBuf , cbBuf);295 RT_NOREF2(pvBuf2, cbBuf2); 291 296 292 297 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 319 324 pStreamOut->Props.cBits, pStreamOut->Props.fSigned, cSamplesToSend)); 320 325 321 uint32_t csRead = 0;326 uint32_t csReadTotal = 0; 322 327 323 328 int rc; … … 329 334 330 335 /** @todo For now we ASSUME 25 FPS. */ 331 uint16_t csFrameSize = /*pStreamOut->Props.uHz*/ 48000 / 25; 332 size_t cbFrameSize = AUDIOMIXBUF_S2B(&pStream->MixBuf, csFrameSize); 333 334 rc = AudioMixBufReadCirc(&pStream->MixBuf, (uint8_t *)&pStreamOut->pvFrameBuf[pStreamOut->offFrameBufWrite], 335 pStreamOut->cbFrameBufSize - pStreamOut->offFrameBufWrite, &csRead); 336 if (RT_SUCCESS(rc)) 337 { 338 const uint32_t cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead); 339 340 pStreamOut->offFrameBufWrite = 341 (pStreamOut->offFrameBufWrite + cbRead) % pStreamOut->cbFrameBufSize; 342 Assert(pStreamOut->offFrameBufWrite <= pStreamOut->cbFrameBufSize); 343 pStreamOut->cbFrameBufUsed += cbRead; 344 Assert(pStreamOut->cbFrameBufUsed <= pStreamOut->cbFrameBufSize); 345 346 if (pStreamOut->cbFrameBufUsed >= cbFrameSize) 336 uint16_t cbFrameSize = (/*pStreamOut->Props.uHz*/ 48000 / 25 /* FPS */); 337 338 PRTCIRCBUF pCircBuf = pStreamOut->pCircBuf; 339 340 while (pStreamOut->cbFrameBufUsed < cbFrameSize) 341 { 342 void *pvBuf; 343 size_t cbBuf; 344 RTCircBufAcquireWriteBlock(pCircBuf, RTCircBufFree(pCircBuf), &pvBuf, &cbBuf); 345 346 uint32_t cbRead = 0; 347 348 if (cbBuf) 347 349 { 348 /* Opus always encodes PER FRAME, that is, 2.5, 5, 10, 20, 40 or 60 ms of audio data. */ 350 uint32_t csRead = 0; 351 rc = AudioMixBufReadCirc(&pStream->MixBuf, pvBuf, cbBuf, &csRead); 352 if (RT_SUCCESS(rc)) 353 { 354 AudioMixBufFinish(&pStream->MixBuf, csRead); 355 356 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead); 357 csReadTotal += csRead; 358 } 359 } 360 361 RTCircBufReleaseWriteBlock(pCircBuf, cbRead); 362 363 if ( RT_FAILURE(rc) 364 || !cbRead) 365 { 366 break; 367 } 368 369 if (RTCircBufUsed(pCircBuf) >= cbFrameSize) 370 { 371 uint8_t abSrc[_4K]; 372 size_t cbSrc = 0; 373 374 while (cbSrc < cbFrameSize) 375 { 376 RTCircBufAcquireReadBlock(pCircBuf, cbFrameSize - cbSrc, &pvBuf, &cbBuf); 377 378 if (cbBuf) 379 { 380 memcpy(&abSrc[cbSrc], pvBuf, cbBuf); 381 382 cbSrc += cbBuf; 383 Assert(cbSrc <= sizeof(abSrc)); 384 } 385 386 RTCircBufReleaseReadBlock(pCircBuf, cbBuf); 387 388 if (!cbBuf) 389 break; 390 } 391 392 /* 393 * Opus always encodes PER FRAME, that is, 2.5, 5, 10, 20, 40 or 60 ms of audio data. 394 * 395 * A packet can have up to 120ms worth of audio data. 396 * Anything > 120ms of data will result in a "corrupted package" error message by 397 * by decoding application. 398 */ 349 399 uint8_t abDst[_4K]; 350 400 size_t cbDst = sizeof(abDst); 351 401 352 402 /* Call the encoder to encode our input samples. */ 403 opus_encoder_ctl(pStreamOut->Codec.Opus.pEnc, OPUS_SET_BITRATE(196000)); /** @todo */ 353 404 opus_int32 cbWritten = opus_encode(pStreamOut->Codec.Opus.pEnc, 354 (opus_int16 *)&pStreamOut->pvFrameBuf[pStreamOut->offFrameBufRead], 355 csFrameSize, abDst, cbDst); 405 (opus_int16 *)abSrc, cbSrc, abDst, cbDst); 356 406 if (cbWritten > 0) 357 407 { 358 pStreamOut->offFrameBufRead = (pStreamOut->offFrameBufRead + cbWritten) % pStreamOut->cbFrameBufSize;359 Assert(pStreamOut->cbFrameBufUsed >= cbFrameSize);360 pStreamOut->cbFrameBufUsed -= cbFrameSize;361 362 408 /* Call the WebM writer to actually write the encoded audio data. */ 363 409 WebMWriter::BlockData_Opus blockData = { abDst, cbDst }; 364 rc = pThis->pEBML->WriteBlock( WebMWriter::BlockType_Audio, &blockData, sizeof(blockData));410 rc = pThis->pEBML->WriteBlock(pThis->uTrack, &blockData, sizeof(blockData)); 365 411 AssertRC(rc); 366 412 } 367 413 else if (cbWritten < 0) 414 { 368 415 AssertMsgFailed(("Encoding failed: %s\n", opus_strerror(cbWritten))); 416 rc = VERR_INVALID_PARAMETER; 417 } 418 419 if (RT_FAILURE(rc)) 420 break; 369 421 } 370 422 } … … 372 424 rc = VERR_NOT_SUPPORTED; 373 425 #endif /* VBOX_WITH_LIBOPUS */ 374 375 if (csRead)376 AudioMixBufFinish(&pStream->MixBuf, csRead);377 426 378 427 /* … … 381 430 */ 382 431 if (pcbWritten) 383 *pcbWritten = csRead ;384 385 LogFlowFunc(("csRead =%RU32, rc=%Rrc\n", csRead, rc));432 *pcbWritten = csReadTotal; 433 434 LogFlowFunc(("csReadTotal=%RU32, rc=%Rrc\n", csReadTotal, rc)); 386 435 return rc; 387 436 } … … 393 442 RT_NOREF(pThis); 394 443 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 444 445 if (pStreamOut->pCircBuf) 446 { 447 RTCircBufDestroy(pStreamOut->pCircBuf); 448 pStreamOut->pCircBuf = NULL; 449 } 395 450 396 451 if (pStreamOut->pvFrameBuf) -
trunk/src/VBox/Main/src-client/EbmlWriter.cpp
r65308 r65330 18 18 19 19 #include <list> 20 #include <map> 20 21 #include <stack> 21 22 #include <iprt/asm.h> … … 295 296 struct WebMTrack 296 297 { 297 WebMTrack(WebMTrackType a_enmType, uint 64_t a_offID)298 WebMTrack(WebMTrackType a_enmType, uint8_t a_uTrack, uint64_t a_offID) 298 299 : enmType(a_enmType) 300 , uTrack(a_uTrack) 299 301 , offID(a_offID) 300 302 { 301 u ID = RTRandU32();303 uUUID = RTRandU32(); 302 304 } 303 305 304 306 /** The type of this track. */ 305 307 WebMTrackType enmType; 306 /** The track's UUID. */ 307 uint32_t uID; 308 /** Track parameters. */ 309 union 310 { 311 struct 312 { 313 /** Sample rate of input data. */ 314 uint16_t uHzIn; 315 /** Sample rate the codec is using. */ 316 uint16_t uHzCodec; 317 /** Frame size (in bytes), based on the codec sample rate. */ 318 size_t cbFrameSize; 319 } Audio; 320 }; 321 /** This track's track number. Also used as key in track map. */ 322 uint8_t uTrack; 323 /** The track's "UUID". 324 * Needed in case this track gets mux'ed with tracks from other files. Not really unique though. */ 325 uint32_t uUUID; 308 326 /** Absolute offset in file of track ID. 309 327 * Needed to write the hash sum within the footer. */ … … 367 385 std::list<WebMCueEntry> m_lstCue; 368 386 369 /** List of tracks. */ 370 std::list<WebMTrack> m_lstTracks; 387 /** Map of tracks. 388 * The key marks the track number (*not* the UID!). */ 389 std::map <uint8_t, WebMTrack *> m_mapTracks; 390 /** Whether we're currently in an opened tracks segment. */ 371 391 bool m_fTracksOpen; 372 392 … … 380 400 381 401 Ebml m_Ebml; 402 403 public: 404 405 typedef std::map <uint8_t, WebMTrack *> WebMTracks; 382 406 383 407 public: … … 397 421 , m_offSegClusterStart(0) {} 398 422 399 int AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBits) 423 virtual ~WebMWriter_Impl() 424 { 425 close(); 426 } 427 428 int AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBits, uint8_t *puTrack) 400 429 { 401 430 #ifdef VBOX_WITH_LIBOPUS 402 431 m_Ebml.subStart(TrackEntry); 403 m_Ebml.serializeUnsignedInteger(TrackNumber, (uint8_t)m_ lstTracks.size());432 m_Ebml.serializeUnsignedInteger(TrackNumber, (uint8_t)m_mapTracks.size()); 404 433 /** @todo Implement track's "Language" property? Currently this defaults to English ("eng"). */ 405 434 406 WebMTrack TrackAudio(WebMTrackType_Audio, RTFileTell(m_Ebml.getFile())); 407 m_lstTracks.push_back(TrackAudio); 408 409 if (uHz >= 44100) 410 uHz = 48000; 435 uint8_t uTrack = m_mapTracks.size(); 436 437 WebMTrack *pTrack = new WebMTrack(WebMTrackType_Audio, uTrack, RTFileTell(m_Ebml.getFile())); 438 439 /* Clamp the codec rate value if it reaches a certain threshold. */ 440 if (uHz > 24000) pTrack->Audio.uHzCodec = 48000; 441 else if (uHz > 16000) pTrack->Audio.uHzCodec = 24000; 442 else if (uHz > 12000) pTrack->Audio.uHzCodec = 16000; 443 else if (uHz > 8000 ) pTrack->Audio.uHzCodec = 12000; 444 else pTrack->Audio.uHzCodec = 8000; 445 446 pTrack->Audio.uHzIn = uHz; 447 448 /** @todo 1920 bytes is 40ms worth of audio data. Make this configurable. */ 449 pTrack->Audio.cbFrameSize = 1920 / (48000 / pTrack->Audio.uHzCodec); 411 450 412 451 /** @todo Resolve codec type. */ 413 452 OpusPrivData opusPrivData(uHz, cChannels); 414 453 415 m_Ebml.serializeUnsignedInteger(TrackUID, TrackAudio.uID, 4)454 m_Ebml.serializeUnsignedInteger(TrackUID, pTrack->uUUID, 4) 416 455 .serializeUnsignedInteger(TrackType, 2 /* Audio */) 417 456 .serializeString(CodecID, "A_OPUS") … … 420 459 .serializeUnsignedInteger(SeekPreRoll, 80000000) 421 460 .subStart(Audio) 422 .serializeFloat(SamplingFrequency, (float)uHz)423 .serializeUnsignedInteger(Channels, 424 .serializeUnsignedInteger(BitDepth, 461 .serializeFloat(SamplingFrequency, (float)pTrack->Audio.uHzCodec) 462 .serializeUnsignedInteger(Channels, cChannels) 463 .serializeUnsignedInteger(BitDepth, cBits) 425 464 .subEnd(Audio) 426 465 .subEnd(TrackEntry); 466 467 m_mapTracks[uTrack] = pTrack; 468 469 if (puTrack) 470 *puTrack = uTrack; 427 471 428 472 return VINF_SUCCESS; … … 433 477 } 434 478 435 int AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS )479 int AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS, uint8_t *puTrack) 436 480 { 437 481 m_Ebml.subStart(TrackEntry); 438 m_Ebml.serializeUnsignedInteger(TrackNumber, (uint8_t)m_lstTracks.size()); 439 440 WebMTrack TrackVideo(WebMTrackType_Video, RTFileTell(m_Ebml.getFile())); 441 m_lstTracks.push_back(TrackVideo); 482 m_Ebml.serializeUnsignedInteger(TrackNumber, (uint8_t)m_mapTracks.size()); 483 484 uint8_t uTrack = m_mapTracks.size(); 485 486 WebMTrack *pTrack = new WebMTrack(WebMTrackType_Video, uTrack, RTFileTell(m_Ebml.getFile())); 442 487 443 488 /** @todo Resolve codec type. */ 444 445 m_Ebml.serializeUnsignedInteger(TrackUID, TrackVideo.uID /* UID */, 4) 489 m_Ebml.serializeUnsignedInteger(TrackUID, pTrack->uUUID /* UID */, 4) 446 490 .serializeUnsignedInteger(TrackType, 1 /* Video */) 447 491 .serializeString(CodecID, "V_VP8") … … 452 496 .subEnd(Video) 453 497 .subEnd(TrackEntry); 498 499 m_mapTracks[uTrack] = pTrack; 500 501 if (puTrack) 502 *puTrack = uTrack; 454 503 455 504 return VINF_SUCCESS; … … 510 559 } 511 560 512 int writeBlockVP8(const vpx_codec_enc_cfg_t *a_pCfg, const vpx_codec_cx_pkt_t *a_pPkt) 513 { 561 int writeBlockVP8(const WebMTrack *a_pTrack, const vpx_codec_enc_cfg_t *a_pCfg, const vpx_codec_cx_pkt_t *a_pPkt) 562 { 563 RT_NOREF(a_pTrack); 564 514 565 /* Calculate the PTS of this frame in milliseconds. */ 515 566 int64_t tsPtsMs = a_pPkt->data.frame.pts * 1000 … … 570 621 fFlags |= 0x08; /* Invisible frame. */ 571 622 572 return writeSimpleBlockInternal( 0 /** @todo FIX! */, tsBlockMs, a_pPkt->data.frame.buf, a_pPkt->data.frame.sz, fFlags);623 return writeSimpleBlockInternal(a_pTrack->uTrack, tsBlockMs, a_pPkt->data.frame.buf, a_pPkt->data.frame.sz, fFlags); 573 624 } 574 625 575 626 #ifdef VBOX_WITH_LIBOPUS 576 627 /* Audio blocks that have same absolute timecode as video blocks SHOULD be written before the video blocks. */ 577 int writeBlockOpus(const void *pvData, size_t cbData) 578 { 628 int writeBlockOpus(const WebMTrack *a_pTrack, const void *pvData, size_t cbData) 629 { 630 AssertPtrReturn(a_pTrack, VERR_INVALID_POINTER); 631 AssertReturn(a_pTrack->Audio.cbFrameSize == cbData, VERR_INVALID_PARAMETER); 632 579 633 static uint16_t s_uTimecode = 0; 580 634 … … 586 640 } 587 641 588 return writeSimpleBlockInternal(0 /** @todo FIX! */, s_uTimecode++, pvData, cbData, 0 /* Flags */); 642 uint64_t ts = (s_uTimecode * 1000 * 1000 * 1000) / 48000; 643 644 LogFunc(("ts=%RU64 (timecode %RU16)\n", ts, s_uTimecode)); 645 646 s_uTimecode += a_pTrack->Audio.cbFrameSize; 647 648 return writeSimpleBlockInternal(a_pTrack->uTrack, ts, pvData, cbData, 0 /* Flags */); 589 649 } 590 650 #endif 591 651 592 int WriteBlock( WebMWriter::BlockType blockType, const void *pvData, size_t cbData)652 int WriteBlock(uint8_t uTrack, const void *pvData, size_t cbData) 593 653 { 594 654 RT_NOREF(cbData); /* Only needed for assertions for now. */ 655 656 WebMTracks::const_iterator itTrack = m_mapTracks.find(uTrack); 657 if (itTrack == m_mapTracks.end()) 658 return VERR_NOT_FOUND; 659 660 const WebMTrack *pTrack = itTrack->second; 661 AssertPtr(pTrack); 595 662 596 663 int rc; … … 602 669 } 603 670 604 switch ( blockType)605 { 606 607 case WebM Writer::BlockType_Audio:671 switch (pTrack->enmType) 672 { 673 674 case WebMTrackType_Audio: 608 675 { 609 676 #ifdef VBOX_WITH_LIBOPUS … … 612 679 Assert(cbData == sizeof(WebMWriter::BlockData_Opus)); 613 680 WebMWriter::BlockData_Opus *pData = (WebMWriter::BlockData_Opus *)pvData; 614 rc = writeBlockOpus(p Data->pvData, pData->cbData);681 rc = writeBlockOpus(pTrack, pData->pvData, pData->cbData); 615 682 } 616 683 else … … 620 687 } 621 688 622 case WebM Writer::BlockType_Video:689 case WebMTrackType_Video: 623 690 { 624 691 if (m_enmVideoCodec == WebMWriter::VideoCodec_VP8) … … 626 693 Assert(cbData == sizeof(WebMWriter::BlockData_VP8)); 627 694 WebMWriter::BlockData_VP8 *pData = (WebMWriter::BlockData_VP8 *)pvData; 628 rc = writeBlockVP8(p Data->pCfg, pData->pPkt);695 rc = writeBlockVP8(pTrack, pData->pCfg, pData->pPkt); 629 696 } 630 697 else … … 687 754 } 688 755 756 int close(void) 757 { 758 WebMTracks::iterator itTrack = m_mapTracks.begin(); 759 for (; itTrack != m_mapTracks.end(); ++itTrack) 760 { 761 delete itTrack->second; 762 itTrack = m_mapTracks.erase(itTrack); 763 } 764 765 Assert(m_mapTracks.size() == 0); 766 767 m_Ebml.close(); 768 769 return VINF_SUCCESS; 770 } 771 689 772 friend class Ebml; 690 773 friend class WebMWriter; … … 778 861 779 862 int rc = m_pImpl->writeFooter(); 780 781 /* Close the file in any case. */ 782 m_pImpl->m_Ebml.close(); 863 if (RT_SUCCESS(rc)) 864 m_pImpl->close(); 783 865 784 866 return rc; 785 867 } 786 868 787 int WebMWriter::AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBitDepth )869 int WebMWriter::AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBitDepth, uint8_t *puTrack) 788 870 { 789 return m_pImpl->AddAudioTrack(uHz, cChannels, cBitDepth );871 return m_pImpl->AddAudioTrack(uHz, cChannels, cBitDepth, puTrack); 790 872 } 791 873 792 int WebMWriter::AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS )874 int WebMWriter::AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS, uint8_t *puTrack) 793 875 { 794 return m_pImpl->AddVideoTrack(uWidth, uHeight, dbFPS );876 return m_pImpl->AddVideoTrack(uWidth, uHeight, dbFPS, puTrack); 795 877 } 796 878 797 int WebMWriter::WriteBlock( WebMWriter::BlockType blockType, const void *pvData, size_t cbData)879 int WebMWriter::WriteBlock(uint8_t uTrack, const void *pvData, size_t cbData) 798 880 { 799 881 int rc; … … 801 883 try 802 884 { 803 rc = m_pImpl->WriteBlock( blockType, pvData, cbData);885 rc = m_pImpl->WriteBlock(uTrack, pvData, cbData); 804 886 } 805 887 catch(int rc2) -
trunk/src/VBox/Main/src-client/EbmlWriter.h
r65281 r65330 79 79 }; 80 80 81 /**82 * Block type to write.83 */84 enum BlockType85 {86 BlockType_Invalid = 0,87 BlockType_Audio = 1,88 BlockType_Video = 2,89 BlockType_Raw = 390 };91 92 81 public: 93 82 … … 110 99 int Close(void); 111 100 112 int AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBits );101 int AddAudioTrack(uint16_t uHz, uint8_t cChannels, uint8_t cBits, uint8_t *puTrack); 113 102 114 int AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS );103 int AddVideoTrack(uint16_t uWidth, uint16_t uHeight, double dbFPS, uint8_t *puTrack); 115 104 116 105 /** 117 106 * Writes a block of compressed data. 118 107 * 119 * @param blockType Block type to write.108 * @param uTrack Track number to write data to. 120 109 * @param pvData Pointer to block data to write. 121 110 * @param cbData Size (in bytes) of block data to write. … … 123 112 * @returns VBox status code. 124 113 */ 125 int WriteBlock( WebMWriter::BlockType blockType, const void *pvData, size_t cbData);114 int WriteBlock(uint8_t uTrack, const void *pvData, size_t cbData); 126 115 127 116 /** -
trunk/src/VBox/Main/src-client/VideoRec.cpp
r65263 r65330 109 109 /** Container context. */ 110 110 WebMWriter *pEBML; 111 /** Track number of video stream. */ 112 uint8_t uTrackVideo; 111 113 /** Codec data. */ 112 114 VIDEORECCODEC Codec; … … 754 756 if (fHasVideoTrack) 755 757 { 756 rc = pStream->pEBML->AddVideoTrack(uWidth, uHeight, uFps );758 rc = pStream->pEBML->AddVideoTrack(uWidth, uHeight, uFps, &pStream->uTrackVideo); 757 759 if (RT_FAILURE(rc)) 758 760 { … … 914 916 { 915 917 WebMWriter::BlockData_VP8 blockData = { &pStream->Codec.VPX.Config, pPacket }; 916 rc = pStream->pEBML->WriteBlock( WebMWriter::BlockType_Video, &blockData, sizeof(blockData));918 rc = pStream->pEBML->WriteBlock(pStream->uTrackVideo, &blockData, sizeof(blockData)); 917 919 break; 918 920 }
Note:
See TracChangeset
for help on using the changeset viewer.