📄 quicktimeliveimagestream.cpp
字号:
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details.*/#include <cstdlib>#include <osg/Notify>#include <osg/Timer>#include <osg/ref_ptr>#include <osg/Referenced>#include <osg/Notify>#include <osgDB/Registry>#include <osg/GL>#include <osg/Endian>#include <osg/Timer>#include <osgDB/FileNameUtils>#include <OpenThreads/ScopedLock>#include <OpenThreads/Thread>#include "QuicktimeLiveImageStream.h"#include "QTLiveUtils.h"// Constructor: setup and start threadQuicktimeLiveImageStream::QuicktimeLiveImageStream(std::string fileName) : ImageStream(){ setOrigin(osg::Image::TOP_LEFT); _status = ImageStream::PAUSED; //probe_video_digitizer_components(); //probe_sequence_grabber_components(); // Initialise QT // initialize_quicktime_qtml(); // enter_quicktime_movies(); // load(fileName);}// Deconstructor: stop and terminate threadQuicktimeLiveImageStream::~QuicktimeLiveImageStream(){ // Terminate QT // leave_quicktime_movies(); // terminite_quicktime_qtml();}/// Start or continue stream.void QuicktimeLiveImageStream::play(){ osg::notify(osg::DEBUG_INFO)<<"Sending play"<<this<<std::endl; /* if (g_s_use_sg) { ComponentResult result = noErr; result = SGStartPreview(m_gSeqGrabber); if (result != noErr) osg::notify(osg::FATAL) << "SGStartPreview : error" << std::endl; }*/}/// Pause stream at current position.void QuicktimeLiveImageStream::pause(){ osg::notify(osg::DEBUG_INFO)<<"Sending pause"<<this<<std::endl;}/// stop playing void QuicktimeLiveImageStream::quit(bool wiatForThreadToExit){ osg::notify(osg::DEBUG_INFO)<<"Sending quit"<<this<<std::endl;}//// PRIVATE//// Use the Sequence Grabber or the raw Video Digitizer// If using SG then use it in Preview or Record option// Thre options - VD Play Through, SG Preview or SG Recordstatic bool g_s_use_sg = true ; // 1astatic bool g_s_use_sg_record = false; // 1b// loadvoid QuicktimeLiveImageStream::load(std::string fileName){ osg::notify(osg::DEBUG_INFO)<<"QuicktimeLive Loading..."<<this<<std::endl; // CreateAndRunWithSequenceGrabber if (g_s_use_sg) createAndRunWithSequenceGrabber(fileName); else createAndRunWithVideoDigitizer(fileName);}// Create the Imagevoid QuicktimeLiveImageStream::createImage(){ // Old // char* pointer = (char*)malloc(4 * m_videoRectWidth*m_videoRectHeight + 32); // void* buffer = (void*)(((unsigned long)(pointer + 31) >> 5) << 5); // New int* buffer = new int [m_videoRectWidth*m_videoRectHeight]; // 1024*1024*4 bytes (32bit RGBA) // GLenum internalFormat = (osg::getCpuByteOrder()==osg::BigEndian)? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_INT_8_8_8_8; setImage(m_videoRectWidth,m_videoRectHeight,1, (GLint) GL_RGBA8, (GLenum)GL_BGRA_EXT, internalFormat, (unsigned char*)buffer,osg::Image::NO_DELETE,4);}// Create the offscreen GWorld (using Image as target memory)void QuicktimeLiveImageStream::createGWorld(){ Rect destinationBounds; OSStatus err; GDHandle origDevice; CGrafPtr origPort; destinationBounds.left = 0; destinationBounds.top = 0; destinationBounds.right = m_videoRectWidth; destinationBounds.bottom = m_videoRectHeight; err = QTNewGWorldFromPtr(&m_gw, k32ARGBPixelFormat, &destinationBounds, NULL, NULL, 0, (Ptr)data(), 4*m_videoRectWidth); if (err !=0 ) { osg::notify(osg::DEBUG_INFO) << "Could not create gWorld" << std::endl; } else { // Query GetGWorld (&origPort, &origDevice); SetGWorld (m_gw, NULL); // set current graphics port to offscreen m_pixmap = GetGWorldPixMap(m_gw); if (m_pixmap) { if (!LockPixels (m_pixmap)) // lock offscreen pixel map { osg::notify(osg::FATAL) << "Could not lock PixMap" << std::endl; } } // Set back SetGWorld(origPort, origDevice); }}// 1.// CreateAndRunWithSequenceGrabbervoid QuicktimeLiveImageStream::createAndRunWithSequenceGrabber(std::string fileName){ std::string::size_type idx = fileName.find(':'); if (idx == std::string::npos) { osg::notify(osg::FATAL) << "Error while parsing deviceID:deviceInputID.live path : " << fileName << std::endl; } // Better c++ code is to use istrstream std::string deviceIDStr = fileName.substr(0,idx); std::string deviceInputIDStr = fileName.substr(idx+1); m_videoDeviceID = static_cast<short>(atoi(deviceIDStr.c_str())); m_videoDeviceInputID = static_cast<short>(atoi(deviceInputIDStr.c_str())); // Get Video Digitizer Rectangle bounds from a Sequence Grabber proxy (using IDs) get_video_device_bounds_idstr(m_videoDeviceID, m_videoDeviceInputID, m_videoRectWidth, m_videoRectHeight, m_videoDeviceIDStr); // Sound m_soundDeviceID = 2; m_soundDeviceInputID = 0; //get_sound_device_idstr(m_soundDeviceID, m_soundDeviceInputID, m_soundDeviceIDStr); // Create the Image createImage(); // Create the offscreen GWorld (using Image as target memory) createGWorld(); // Create the Sequence Grabber (using GWorld as target memory) createSequenceGrabber(); // Create the Sequence Grabber Video Channel createSequenceGrabberVideoChannel(); if (g_s_use_sg_record) { // Create the Sequence Grabber DataProc setup for Record createSequenceGrabberDataProc(); } // Create the Sequence Grabber Audio Channel createSequenceGrabberAudioChannel(); // Start the engine Jack! // Callbacks createSequenceGrabberVideoBottlenecks(); ComponentResult result = noErr; result = SGPrepare( m_gSeqGrabber, TRUE, FALSE); if (result != noErr) osg::notify(osg::FATAL) << "SGPrepare : error" << std::endl; if (g_s_use_sg_record) { result = SGStartRecord(m_gSeqGrabber); if (result != noErr) osg::notify(osg::FATAL) << "SGStartRecord : error" << std::endl; } else { result = SGStartPreview(m_gSeqGrabber); if (result != noErr) osg::notify(osg::FATAL) << "SGStartPreview : error" << std::endl; } _status = ImageStream::PLAYING; // Ticker start();}// 1.// Create the Sequence Grabber (using GWorld as target memory)void QuicktimeLiveImageStream::createSequenceGrabber(){ ComponentDescription sg_component_description; sg_component_description.componentType = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */ sg_component_description.componentSubType = 0L; /* Particular flavor of this instance */ sg_component_description.componentManufacturer = 'appl'; /* Vendor indentification */ sg_component_description.componentFlags = 0L; /* 8 each for Component,Type,SubType,Manuf/revision */ sg_component_description.componentFlagsMask = 0L; /* Mask for specifying which flags to consider in search, zero during registration */ long num_sg_components = CountComponents (&sg_component_description); if (num_sg_components) { Component aComponent = 0; ComponentDescription full_sg_component_description = sg_component_description; aComponent = FindNextComponent(aComponent, &full_sg_component_description); if (aComponent) { m_gSeqGrabber = OpenComponent(aComponent); // If we got a sequence grabber, set it up if (m_gSeqGrabber != 0L) { // Check capability and setting of Sequence Grabber GDHandle origDevice; CGrafPtr origPort; // Create GWorld GetGWorld (&origPort, &origDevice); SetGWorld (m_gw, NULL); // set current graphics port to offscreen // Initialize the sequence grabber ComponentResult result = noErr; result = SGInitialize (m_gSeqGrabber); if (result == noErr) { // Set GWorld result = SGSetGWorld(m_gSeqGrabber, (CGrafPtr)m_gw, 0); if (result != noErr) { osg::notify(osg::FATAL) << "Could not set GWorld on SG" << std::endl; } } // Set GWorld back SetGWorld(origPort, origDevice); } } }}// Create the Sequence Grabber Video Channelvoid QuicktimeLiveImageStream::createSequenceGrabberVideoChannel(){ // Check capability and setting of Sequence Grabber GDHandle origDevice; CGrafPtr origPort; // Create GWorld GetGWorld (&origPort, &origDevice); SetGWorld (m_gw, NULL); // set current graphics port to offscreen // Setup // Get a video channel ComponentResult result = SGNewChannel (m_gSeqGrabber, VideoMediaType, &m_gVideoChannel); if ((m_gVideoChannel != nil) && (result == noErr)) { result = SGInitChannel(m_gVideoChannel, m_gSeqGrabber); Rect gActiveVideoRect; // Usage if (g_s_use_sg_record) result = SGSetChannelUsage (m_gVideoChannel, seqGrabRecord | seqGrabLowLatencyCapture); else { result = SGSetChannelUsage (m_gVideoChannel, seqGrabPreview); } // result = SGSetUseScreenBuffer(m_gVideoChannel, FALSE); // Set osg::notify(osg::DEBUG_INFO) << "Setting up vdig from input prefs" << std::endl; result = SGSetChannelDevice ( m_gVideoChannel, m_videoDeviceIDStr); result = SGSetChannelDeviceInput( m_gVideoChannel, m_videoDeviceInputID); // result = SGSetChannelPlayFlags ( m_gVideoChannel, channelPlayFast | channelPlayHighQuality | channelPlayAllData); result = SGSetChannelPlayFlags ( m_gVideoChannel, channelPlayFast ); VideoDigitizerComponent vdig = SGGetVideoDigitizerComponent(m_gVideoChannel); VideoDigitizerError vid_err; vid_err = VDSetInputStandard (vdig, palIn); osg::notify(osg::DEBUG_INFO) << "Setup vdig from input prefs:" << std::endl; print_video_component_capability(vdig);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -