Changeset 34969 in vbox
- Timestamp:
- Dec 10, 2010 7:08:32 PM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/filteraudio.c
r34910 r34969 257 257 * or the device itself is changed during the runtime. */ 258 258 volatile uint32_t status; 259 260 /* the stream has been successfully initialized by host. */ 261 bool fHostOK; 259 262 260 263 /* Whether the input stream is used by the filter. */ … … 508 511 ******************************************************************************/ 509 512 510 /* We need some forward declarations */511 static int filteraudio_run_in(HWVoiceIn *hw);512 static int filteraudio_read(SWVoiceIn *sw, void *buf, int size);513 static int filteraudio_ctl_in(HWVoiceIn *hw, int cmd, ...);514 static void filteraudio_fini_in(HWVoiceIn *hw);515 static int filteraudio_init_in(HWVoiceIn *hw, audsettings_t *as);516 517 513 /* 518 514 * Callback to feed audio input buffer. Samples format is be the same as 519 * in the voice. The caller prepares st sample_t.515 * in the voice. The caller prepares st_sample_t. 520 516 * 521 517 * @param cbSamples Size of pvSamples array in bytes. … … 595 591 char *pcSrc; 596 592 st_sample_t *psDst; 597 598 filterVoiceIn *pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 593 filterVoiceIn *pVoice; 594 595 if (!filter_conf.pDrv) 596 { 597 AssertFailed(); 598 return -1; 599 } 600 601 pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 599 602 600 603 if (!pVoice->fIntercepted) … … 662 665 { 663 666 int rc = VINF_SUCCESS; 664 665 filterVoiceIn *pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 666 667 if (!pVoice->fIntercepted) 668 { 669 /* Note: audio.c does not use variable parameters '...', so ok to forward only 'phw' and 'cmd'. */ 670 Log(("FilterAudio: [Input]: forwarding ctl_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 671 return filter_conf.pDrv->pcm_ops->ctl_in(phw, cmd); 672 } 673 674 Log(("FilterAudio: [Input]: ctl_in for voice %p (hw %p), cmd %d\n", pVoice, pVoice->phw, cmd)); 675 676 if (ASMAtomicReadU32(&pVoice->status) != CA_STATUS_INIT) 677 return 0; 678 679 switch (cmd) 680 { 681 case VOICE_ENABLE: 667 filterVoiceIn *pVoice; 668 669 if (!filter_conf.pDrv) 670 { 671 AssertFailed(); 672 return -1; 673 } 674 675 pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 676 677 if (cmd == VOICE_ENABLE) 678 { 679 /* Decide who will provide input audio: filter or host driver. */ 680 if (!filter_input_intercepted()) 682 681 { 683 /* Only start the device if it is actually stopped */ 684 if (!pVoice->fIsRunning) 682 if (!pVoice->fHostOK) 685 683 { 686 IORingBufferReset(pVoice->pBuf); 687 688 /* Sniffer will inform us on a second thread for new incoming audio data. 689 * Therefore register an callback function, which will process the new data. 690 * */ 691 rc = filter_input_begin(&pVoice->pvInputCtx, fltRecordingCallback, pVoice, pVoice->phw, pVoice->phw->samples); 692 if (RT_SUCCESS(rc)) 693 { 694 pVoice->fIsRunning = true; 695 } 696 } 697 if (RT_FAILURE(rc)) 698 { 699 LogRel(("FilterAudio: [Input] Failed to start recording (%Rrc)\n", rc)); 684 /* Host did not initialize the voice. */ 685 Log(("FilterAudio: [Input]: ctl_in ENABLE voice %p (hw %p) not available on host\n", pVoice, pVoice->phw)); 700 686 return -1; 701 687 } 702 break; 688 689 /* Note: audio.c does not use variable parameters '...', so ok to forward only 'phw' and 'cmd'. */ 690 Log(("FilterAudio: [Input]: forwarding ctl_in ENABLE for voice %p (hw %p)\n", pVoice, pVoice->phw)); 691 return filter_conf.pDrv->pcm_ops->ctl_in(phw, cmd); 703 692 } 704 case VOICE_DISABLE: 693 694 /* The filter will use this voice. */ 695 Log(("FilterAudio: [Input]: ctl_in ENABLE for voice %p (hw %p), cmd %d\n", pVoice, pVoice->phw, cmd)); 696 697 if (ASMAtomicReadU32(&pVoice->status) != CA_STATUS_INIT) 698 return -1; 699 700 /* Only start the device if it is actually stopped */ 701 if (!pVoice->fIsRunning) 705 702 { 706 /* Only stop the device if it is actually running */ 707 if (pVoice->fIsRunning) 703 IORingBufferReset(pVoice->pBuf); 704 705 /* Sniffer will inform us on a second thread for new incoming audio data. 706 * Therefore register an callback function, which will process the new data. 707 * */ 708 rc = filter_input_begin(&pVoice->pvInputCtx, fltRecordingCallback, pVoice, pVoice->phw, pVoice->phw->samples); 709 if (RT_SUCCESS(rc)) 708 710 { 709 pVoice->fIsRunning = false; 710 /* Tell the sniffer to not to use this context anymore. */ 711 filter_input_end(pVoice->pvInputCtx); 711 pVoice->fIsRunning = true; 712 713 /* Remember that this voice is used by the filter. */ 714 pVoice->fIntercepted = true; 712 715 } 713 break;714 716 } 715 } 717 if (RT_FAILURE(rc)) 718 { 719 LogRel(("FilterAudio: [Input] Failed to start recording (%Rrc)\n", rc)); 720 return -1; 721 } 722 } 723 else if (cmd == VOICE_DISABLE) 724 { 725 if (ASMAtomicReadU32(&pVoice->status) != CA_STATUS_INIT) 726 return -1; 727 728 /* Check if the voice has been intercepted. */ 729 if (!pVoice->fIntercepted) 730 { 731 /* Note: audio.c does not use variable parameters '...', so ok to forward only 'phw' and 'cmd'. */ 732 Log(("FilterAudio: [Input]: forwarding ctl_in DISABLE for voice %p (hw %p)\n", pVoice, pVoice->phw)); 733 return filter_conf.pDrv->pcm_ops->ctl_in(phw, cmd); 734 } 735 736 /* The filter used this voice. */ 737 Log(("FilterAudio: [Input]: ctl_in DISABLE for voice %p (hw %p), cmd %d\n", pVoice, pVoice->phw, cmd)); 738 739 /* Only stop the device if it is actually running */ 740 if (pVoice->fIsRunning) 741 { 742 pVoice->fIsRunning = false; 743 /* Tell the sniffer to not to use this context anymore. */ 744 filter_input_end(pVoice->pvInputCtx); 745 } 746 747 /* This voice is no longer used by the filter. */ 748 pVoice->fIntercepted = false; 749 } 750 else 751 { 752 return -1; /* Unknown command. */ 753 } 754 716 755 return 0; 717 756 } … … 720 759 { 721 760 int ret = -1; 722 723 filterVoiceIn *pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 724 725 /* Only pass voices, which are not intercepted. */ 726 if (!pVoice->fIntercepted) 727 { 728 Log(("FilterAudio: [Input]: forwarding fini_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 729 filter_conf.pDrv->pcm_ops->fini_in(phw); 761 filterVoiceIn *pVoice; 762 763 if (!filter_conf.pDrv) 764 { 765 AssertFailed(); 730 766 return; 731 767 } 768 769 pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 770 771 /* Uninitialize both host and filter parts of the voice. */ 772 Log(("FilterAudio: [Input]: forwarding fini_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 773 filter_conf.pDrv->pcm_ops->fini_in(phw); 732 774 733 775 Log(("FilterAudio: [Input]: fini_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); … … 736 778 return; 737 779 738 ret = filteraudio_ctl_in(phw, VOICE_DISABLE); 780 /* If this voice is intercepted by filter, try to stop it. */ 781 if (pVoice->fIntercepted) 782 { 783 ret = filteraudio_ctl_in(phw, VOICE_DISABLE); 784 } 785 else 786 { 787 ret = 0; 788 } 789 739 790 if (RT_LIKELY(ret == 0)) 740 791 { … … 751 802 static int filteraudio_init_in(HWVoiceIn *phw, audsettings_t *as) 752 803 { 753 filterVoiceIn *pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 754 755 if (!filter_input_intercepted()) 756 { 757 Log(("FilterAudio: [Input]: forwarding init_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 758 pVoice->fIntercepted = false; 759 return filter_conf.pDrv->pcm_ops->init_in(phw, as); 760 } 761 762 Log(("FilterAudio: [Input]: init_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 804 int hostret = -1; 805 filterVoiceIn *pVoice; 806 807 if (!filter_conf.pDrv) 808 { 809 AssertFailed(); 810 return -1; 811 } 812 813 pVoice = (filterVoiceIn *)((uint8_t *)phw + filter_conf.pDrv->voice_size_in); 814 815 /* Initialize both host and filter parts of the voice. */ 816 Log(("FilterAudio: [Input]: forwarding init_in for voice %p (hw %p)\n", pVoice, pVoice->phw)); 817 hostret = filter_conf.pDrv->pcm_ops->init_in(phw, as); 818 819 Log(("FilterAudio: [Input]: init_in for voice %p (hw %p), hostret = %d\n", pVoice, pVoice->phw, hostret)); 763 820 764 821 ASMAtomicWriteU32(&pVoice->status, CA_STATUS_UNINIT); … … 767 824 pVoice->rpos = 0; 768 825 pVoice->pBuf = NULL; 769 /* Remember that this voice belongs to the filter. */770 pVoice->fIntercepted = true;826 pVoice->fHostOK = (hostret == 0); 827 pVoice->fIntercepted = false; 771 828 pVoice->fIsRunning = false; 772 829 pVoice->pvInputCtx = NULL; 773 830 774 /* The ring buffer must be big enough to hold specified number of samples. 775 * A sample includes all channels. 776 */ 777 pVoice->phw->samples = 2048; 778 779 /* Initialize the hardware info section with the audio settings */ 780 audio_pcm_init_info(&pVoice->phw->info, as); 831 if (!pVoice->fHostOK) 832 { 833 /* Initialize required fields of the common part of the voice. */ 834 pVoice->phw->samples = 2048; 835 836 /* Initialize the hardware info section with the audio settings */ 837 audio_pcm_init_info(&pVoice->phw->info, as); 838 } 781 839 782 840 ASMAtomicWriteU32(&pVoice->status, CA_STATUS_IN_INIT); … … 794 852 795 853 Log(("FilterAudio: [Input] HW samples: %d\n", pVoice->phw->samples)); 796 797 854 return 0; 798 855 } … … 806 863 static void *filteraudio_audio_init(void) 807 864 { 808 return &filter_conf; 865 /* This is not supposed to be called. */ 866 Log(("FilterAudio: Init\n")); 867 AssertFailed(); 868 return NULL; 809 869 } 810 870 811 871 static void filteraudio_audio_fini(void *opaque) 812 872 { 813 NOREF(opaque); 873 Log(("FilterAudio: Init fini %p\n", opaque)); 874 /* Forward to the host driver. */ 875 Assert(opaque == filter_conf.pDrvOpaque); 876 if (filter_conf.pDrv) 877 { 878 filter_conf.pDrv->fini(opaque); 879 filter_conf.pDrv = NULL; 880 } 814 881 } 815 882 -
trunk/src/VBox/Main/ConsoleVRDPServer.cpp
r34959 r34969 863 863 if (pPort) 864 864 { 865 // @todo dynamic filter attach does not yet workpPort->pfnAudioInputIntercept(pPort, false);865 pPort->pfnAudioInputIntercept(pPort, false); 866 866 } 867 867 else … … 920 920 if (pPort) 921 921 { 922 // @todo dynamic filter attach does not yet workpPort->pfnAudioInputIntercept(pPort, true);922 pPort->pfnAudioInputIntercept(pPort, true); 923 923 if (ppvIntercept) 924 924 { … … 2269 2269 audioFormat, 2270 2270 cSamples); 2271 *ppvUserCtx = NULL; /* This is the ConsoleVRDP server context.2271 *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context. 2272 2272 * Currently not used because only one client is allowed to 2273 2273 * do audio input and the client id is saved by the ConsoleVRDPServer.
Note:
See TracChangeset
for help on using the changeset viewer.