~ubuntu-branches/ubuntu/trusty/openscenegraph/trusty

« back to all changes in this revision

Viewing changes to OpenSceneGraph/src/osgPlugins/QTKit/VideoFrameDispatcher.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-11-12 02:21:14 UTC
  • mfrom: (31.1.3 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20131112022114-qaxfhdnhn88vnh10
Tags: 3.2.0~rc1-1ubuntu1
Fix deprecated url_feof.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
 
3
 *
 
4
 * This library is open source and may be redistributed and/or modified under
 
5
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 
6
 * (at your option) any later version.  The full license is in LICENSE file
 
7
 * included with this distribution, and on the openscenegraph.org website.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * OpenSceneGraph Public License for more details.
 
13
*/
 
14
 
 
15
#include "VideoFrameDispatcher.h"
 
16
#include <iostream>
 
17
#include <osg/Timer>
 
18
 
 
19
namespace osgVideo {
 
20
 
 
21
VideoImageStream::VideoImageStream()
 
22
    : osg::ImageStream()
 
23
    , _needsDispatching(false)
 
24
    , _dispatcher(NULL)
 
25
    , _queue(NULL)
 
26
{
 
27
}
 
28
 
 
29
VideoImageStream::VideoImageStream(const VideoImageStream& image,const osg::CopyOp& copyop)
 
30
    : osg::ImageStream(image, copyop)
 
31
    , _needsDispatching(image._needsDispatching)
 
32
    , _dispatcher(image._dispatcher)
 
33
    , _queue(NULL)
 
34
{
 
35
}
 
36
 
 
37
VideoImageStream::~VideoImageStream()
 
38
{
 
39
    setNeedsDispatching(StopUpdate);
 
40
    _dispatcher = NULL;
 
41
}
 
42
 
 
43
bool VideoImageStream::setNeedsDispatching(RequestMode request_mode)
 
44
{
 
45
    _needsDispatching = (_needsDispatching || (request_mode == RequestContinuousUpdate)) && (request_mode != StopUpdate);
 
46
    if (!_dispatcher)
 
47
        return false;
 
48
    
 
49
    if (request_mode == StopUpdate) {
 
50
        _dispatcher->removeFromQueue(this);
 
51
    }
 
52
    else
 
53
    {
 
54
        _dispatcher->addToQueue(this);
 
55
    }
 
56
    
 
57
    return (_dispatcher != NULL);
 
58
}
 
59
 
 
60
#pragma mark 
 
61
 
 
62
VideoFrameDispatchQueue::VideoFrameDispatchQueue()
 
63
    : OpenThreads::Thread()
 
64
    , osg::Referenced()
 
65
    , _queue()
 
66
    , _numItems(0)
 
67
    , _block()
 
68
    , _mutex()
 
69
    , _finished(false)
 
70
{
 
71
}
 
72
 
 
73
void VideoFrameDispatchQueue::run()
 
74
{
 
75
    osg::Timer t;
 
76
    static unsigned int frame_delay = 1000 * 1000 / 120;
 
77
    
 
78
    _block.reset();
 
79
    _block.block();
 
80
    
 
81
    while(!_finished)
 
82
    {
 
83
        unsigned int num_items(0);
 
84
        {
 
85
            osg::Timer_t last_tick(t.tick());
 
86
            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
 
87
            for(Queue::iterator i = _queue.begin(); i != _queue.end(); )
 
88
            {
 
89
                osg::observer_ptr<VideoImageStream> stream(*i);
 
90
                
 
91
                if (stream.valid() && stream->needsDispatching())
 
92
                {
 
93
                    if (stream.valid())
 
94
                        stream->decodeFrame();
 
95
                    ++num_items;
 
96
                    ++i;
 
97
                }
 
98
                else
 
99
                {
 
100
                    if (stream.valid())
 
101
                        stream->setDispatchQueue(NULL);
 
102
                    _queue.erase(i++);
 
103
                }
 
104
                
 
105
            }
 
106
            _numItems = num_items;
 
107
            if (_numItems > 0)
 
108
            {
 
109
                unsigned int dt = t.delta_u(last_tick, t.tick());
 
110
                if (dt < frame_delay) {
 
111
                    OpenThreads::Thread::microSleep(frame_delay - dt);
 
112
                }
 
113
            }
 
114
        }
 
115
        
 
116
        if (_numItems == 0)
 
117
        {
 
118
            // std::cout << this << " blocking" << std::endl;
 
119
            _block.reset();
 
120
            _block.block();
 
121
        }
 
122
        
 
123
    }
 
124
}
 
125
 
 
126
void VideoFrameDispatchQueue::addItem(osgVideo::VideoImageStream *stream)
 
127
{
 
128
    if (_finished) return;
 
129
    
 
130
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
 
131
    _queue.insert(stream);
 
132
    stream->setDispatchQueue(this);
 
133
    
 
134
    _numItems = _queue.size();
 
135
    _block.release();
 
136
    // std::cout << this << " release" << std::endl;
 
137
}
 
138
 
 
139
void VideoFrameDispatchQueue::removeItem(osgVideo::VideoImageStream* stream)
 
140
{
 
141
    stream->setDispatchQueue(NULL);
 
142
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
 
143
    _queue.erase(stream);
 
144
    _numItems = _queue.size();
 
145
}
 
146
 
 
147
VideoFrameDispatchQueue::~VideoFrameDispatchQueue()
 
148
{
 
149
    _finished = true;
 
150
    _block.release();
 
151
    join();
 
152
}
 
153
 
 
154
#pragma mark
 
155
 
 
156
VideoFrameDispatcher::VideoFrameDispatcher(unsigned int num_threads)
 
157
    : osg::Referenced()
 
158
    , _queues()
 
159
{
 
160
    num_threads = num_threads ? num_threads : OpenThreads::GetNumberOfProcessors();
 
161
    OSG_ALWAYS << "VideoFrameDispatcher: creating " << num_threads << " queues." << std::endl;
 
162
    for(unsigned int i = 0; i < num_threads; ++i)
 
163
    {
 
164
        VideoFrameDispatchQueue* q = new VideoFrameDispatchQueue();
 
165
        q->start();
 
166
        _queues.push_back(q);
 
167
    }
 
168
}
 
169
 
 
170
 
 
171
void VideoFrameDispatcher::addToQueue(VideoImageStream *stream)
 
172
{
 
173
    stream->setThreadSafeRefUnref(true);
 
174
    if (stream->getDispatchQueue())
 
175
        return;
 
176
    
 
177
    VideoFrameDispatchQueue* queue = *std::min_element(_queues.begin(), _queues.end(), VideoFrameDispatchQueueComparator());
 
178
    queue->addItem(stream);
 
179
}
 
180
 
 
181
void VideoFrameDispatcher::removeFromQueue(VideoImageStream* stream)
 
182
{
 
183
   if (stream->getDispatchQueue())
 
184
        stream->getDispatchQueue()->removeItem(stream);
 
185
}
 
186
 
 
187
}
 
 
b'\\ No newline at end of file'