1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 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
26FramedSource::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
34FramedSource::~FramedSource() {
35}
36
37Boolean FramedSource::isFramedSource() const {
38 return True;
39}
40
41Boolean 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
57void 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
81void 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
96void FramedSource::handleClosure(void* clientData) {
97 FramedSource* source = (FramedSource*)clientData;
98 source->handleClosure();
99}
100
101void FramedSource::handleClosure() {
102 fIsCurrentlyAwaitingData = False; // because we got a close instead
103 if (fOnCloseFunc != NULL) {
104 (*fOnCloseFunc)(fOnCloseClientData);
105 }
106}
107
108void 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
117void 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
123unsigned FramedSource::maxFrameSize() const {
124 // By default, this source has no maximum frame size.
125 return 0;
126}
127