1 | /********** |
2 | This library is free software; you can redistribute it and/or modify it under |
3 | the terms of the GNU Lesser General Public License as published by the |
4 | Free Software Foundation; either version 3 of the License, or (at your |
5 | option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
6 | |
7 | This library is distributed in the hope that it will be useful, but WITHOUT |
8 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
9 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
10 | more details. |
11 | |
12 | You should have received a copy of the GNU Lesser General Public License |
13 | along with this library; if not, write to the Free Software Foundation, Inc., |
14 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
15 | **********/ |
16 | // "liveMedia" |
17 | // Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved. |
18 | // Framed Sources |
19 | // Implementation |
20 | |
21 | #include "FramedSource.hh" |
22 | #include <stdlib.h> |
23 | |
24 | ////////// FramedSource ////////// |
25 | |
26 | FramedSource::FramedSource(UsageEnvironment& env) |
27 | : MediaSource(env), |
28 | fAfterGettingFunc(NULL), fAfterGettingClientData(NULL), |
29 | fOnCloseFunc(NULL), fOnCloseClientData(NULL), |
30 | fIsCurrentlyAwaitingData(False) { |
31 | fPresentationTime.tv_sec = fPresentationTime.tv_usec = 0; // initially |
32 | } |
33 | |
34 | FramedSource::~FramedSource() { |
35 | } |
36 | |
37 | Boolean FramedSource::isFramedSource() const { |
38 | return True; |
39 | } |
40 | |
41 | Boolean FramedSource::lookupByName(UsageEnvironment& env, char const* sourceName, |
42 | FramedSource*& resultSource) { |
43 | resultSource = NULL; // unless we succeed |
44 | |
45 | MediaSource* source; |
46 | if (!MediaSource::lookupByName(env, sourceName, source)) return False; |
47 | |
48 | if (!source->isFramedSource()) { |
49 | env.setResultMsg(sourceName, " is not a framed source" ); |
50 | return False; |
51 | } |
52 | |
53 | resultSource = (FramedSource*)source; |
54 | return True; |
55 | } |
56 | |
57 | void FramedSource::getNextFrame(unsigned char* to, unsigned maxSize, |
58 | afterGettingFunc* afterGettingFunc, |
59 | void* afterGettingClientData, |
60 | onCloseFunc* onCloseFunc, |
61 | void* onCloseClientData) { |
62 | // Make sure we're not already being read: |
63 | if (fIsCurrentlyAwaitingData) { |
64 | envir() << "FramedSource[" << this << "]::getNextFrame(): attempting to read more than once at the same time!\n" ; |
65 | envir().internalError(); |
66 | } |
67 | |
68 | fTo = to; |
69 | fMaxSize = maxSize; |
70 | fNumTruncatedBytes = 0; // by default; could be changed by doGetNextFrame() |
71 | fDurationInMicroseconds = 0; // by default; could be changed by doGetNextFrame() |
72 | fAfterGettingFunc = afterGettingFunc; |
73 | fAfterGettingClientData = afterGettingClientData; |
74 | fOnCloseFunc = onCloseFunc; |
75 | fOnCloseClientData = onCloseClientData; |
76 | fIsCurrentlyAwaitingData = True; |
77 | |
78 | doGetNextFrame(); |
79 | } |
80 | |
81 | void FramedSource::afterGetting(FramedSource* source) { |
82 | source->nextTask() = NULL; |
83 | source->fIsCurrentlyAwaitingData = False; |
84 | // indicates that we can be read again |
85 | // Note that this needs to be done here, in case the "fAfterFunc" |
86 | // called below tries to read another frame (which it usually will) |
87 | |
88 | if (source->fAfterGettingFunc != NULL) { |
89 | (*(source->fAfterGettingFunc))(source->fAfterGettingClientData, |
90 | source->fFrameSize, source->fNumTruncatedBytes, |
91 | source->fPresentationTime, |
92 | source->fDurationInMicroseconds); |
93 | } |
94 | } |
95 | |
96 | void FramedSource::handleClosure(void* clientData) { |
97 | FramedSource* source = (FramedSource*)clientData; |
98 | source->handleClosure(); |
99 | } |
100 | |
101 | void FramedSource::handleClosure() { |
102 | fIsCurrentlyAwaitingData = False; // because we got a close instead |
103 | if (fOnCloseFunc != NULL) { |
104 | (*fOnCloseFunc)(fOnCloseClientData); |
105 | } |
106 | } |
107 | |
108 | void FramedSource::stopGettingFrames() { |
109 | fIsCurrentlyAwaitingData = False; // indicates that we can be read again |
110 | fAfterGettingFunc = NULL; |
111 | fOnCloseFunc = NULL; |
112 | |
113 | // Perform any specialized action now: |
114 | doStopGettingFrames(); |
115 | } |
116 | |
117 | void FramedSource::doStopGettingFrames() { |
118 | // Default implementation: Do nothing except cancel any pending 'delivery' task: |
119 | envir().taskScheduler().unscheduleDelayedTask(nextTask()); |
120 | // Subclasses may wish to redefine this function. |
121 | } |
122 | |
123 | unsigned FramedSource::maxFrameSize() const { |
124 | // By default, this source has no maximum frame size. |
125 | return 0; |
126 | } |
127 | |