1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #if defined(PV_RECORD_TO_FILE_SUPPORT)
19 #include "pv_2way_rec_datapath.h"
20 #include "pv_2way_data_channel_datapath.h"
21 //#include "pvmp4ffcn_trackconfig.h"
22
NewL(PVLogger * aLogger,TPV2WayMediaType aFormat,CPV2WayDataChannelDatapath & aDatapath,CPV324m2Way * a2Way)23 CPV2WayRecDatapath *CPV2WayRecDatapath::NewL(PVLogger *aLogger,
24 TPV2WayMediaType aFormat,
25 CPV2WayDataChannelDatapath &aDatapath,
26 CPV324m2Way *a2Way)
27 {
28 CPV2WayRecDatapath *self = OSCL_NEW(CPV2WayRecDatapath, (aLogger, aFormat, aDatapath, a2Way));
29 OsclError::LeaveIfNull(self);
30
31 if (self)
32 {
33 OSCL_TRAPSTACK_PUSH(self);
34 self->ConstructL();
35 }
36
37 OSCL_TRAPSTACK_POP();
38 return self;
39 }
40
CheckPause()41 void CPV2WayRecDatapath::CheckPause()
42 {
43 uint32 i;
44 int32 error;
45
46 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause state %d\n", iState));
47
48 for (i = 0; i < iNodeList.size(); i++)
49 {
50 if (!iNodeList[i].iCanNodePause) continue;
51
52 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause node %d state %d\n", i, iNodeList[i].iNode.node->GetState()));
53 switch (iNodeList[i].iNode.node->GetState())
54 {
55 case EPVMFNodeStarted:
56 OSCL_TRY(error, i2Way->SendNodeCmdL(PV2WAY_NODE_CMD_PAUSE, iNodeList[i].iNode.node, iNodeList[i].iNode.session, this));
57 OSCL_FIRST_CATCH_ANY(error,
58 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckPause unable to pause node\n"));
59 DatapathError();
60 return;);
61 break;
62
63 default:
64 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause transitional node state!\n"));
65 break;
66 }
67 }
68
69 for (i = 0; i < iNodeList.size(); i++)
70 {
71 //If possible pause node is not paused.
72 if (iNodeList[i].iCanNodePause && (iNodeList[i].iNode.node->GetState() != EPVMFNodePaused))
73 {
74 return;
75 }
76 }
77
78 //Disconnect ports
79 for (i = 0; i < iPortPairList.size(); i++)
80 {
81 iPortPairList[i].Disconnect();
82 }
83
84 //If reached this point then the datapath is deemed paused, notify upper layer.
85 SetState(EPaused);
86 PauseComplete();
87 return;
88 }
89
CheckResume()90 void CPV2WayRecDatapath::CheckResume()
91 {
92 uint32 i;
93 int32 error;
94
95 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume state %d\n", iState));
96
97 for (i = 0; i < iNodeList.size(); i++)
98 {
99 if (!iNodeList[i].iCanNodePause) continue;
100
101 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume node %d state %d\n", i, iNodeList[i].iNode.node->GetState()));
102 switch (iNodeList[i].iNode.node->GetState())
103 {
104 case EPVMFNodePaused:
105 OSCL_TRY(error, i2Way->SendNodeCmdL(PV2WAY_NODE_CMD_START, iNodeList[i].iNode.node, iNodeList[i].iNode.session, this));
106 OSCL_FIRST_CATCH_ANY(error,
107 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckResume unable to pause node\n"));
108 DatapathError();
109 return;);
110 break;
111
112 default:
113 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume transitional node state!\n"));
114 break;
115 }
116 }
117
118 for (i = 0; i < iNodeList.size(); i++)
119 {
120 //If possible pause node is not started.
121 if (iNodeList[i].iCanNodePause && (iNodeList[i].iNode.node->GetState() != EPVMFNodeStarted))
122 {
123 return;
124 }
125 }
126
127 //Reconnect ports
128 for (i = 0; i < iPortPairList.size(); i++)
129 {
130 iPortPairList[i].Connect();
131 }
132
133 //If reached this point then the datapath is deemed resumed, notify upper layer.
134 SetState(EOpened);
135 ResumeComplete();
136 return;
137 }
138
SetCmd(TPV2WayCmdInfo * aCmdInfo)139 bool CPV2WayRecDatapath::SetCmd(TPV2WayCmdInfo *aCmdInfo)
140 {
141 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayRecDatapath::SetCmd state %d cmd %x\n", iState, aCmdInfo));
142
143 if (aCmdInfo)
144 {
145 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayRecDatapath::SetCmd cmd type %d\n", aCmdInfo->type));
146 switch (aCmdInfo->type)
147 {
148 case PVT_COMMAND_START_RECORD:
149 if (iState == EOpening) return false;
150 iCmdInfo = aCmdInfo;
151 Open();
152 break;
153
154 case PVT_COMMAND_STOP_RECORD:
155 if (!CloseDatapath(aCmdInfo)) return false;
156 break;
157
158 case PVT_COMMAND_PAUSE_RECORD:
159 if (iState == EPausing) return false;
160 iCmdInfo = aCmdInfo;
161 Pause();
162 break;
163
164 case PVT_COMMAND_RESUME_RECORD:
165 if (iState == EUnpausing) return false;
166 iCmdInfo = aCmdInfo;
167 Resume();
168 break;
169
170 default:
171 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayRecDatapath::SetCmd invalid command\n"));
172 break;
173 }
174
175 }
176 // A null pointer indicates a close for some reason
177 else
178 {
179 if (!CloseDatapath(aCmdInfo)) return false;
180 }
181
182 return true;
183 }
184
OpenComplete()185 void CPV2WayRecDatapath::OpenComplete()
186 {
187 CommandComplete(PVMFSuccess);
188 }
189
CloseComplete()190 void CPV2WayRecDatapath::CloseComplete()
191 {
192 //If parent was closing, then let it notify the app.
193 if (!IsParentClosing())
194 {
195 //If a command was issued
196 if (iCmdInfo)
197 {
198 //If stop command was issued
199 if (iCmdInfo->type == PVT_COMMAND_STOP_RECORD)
200 {
201 CommandComplete(PVMFSuccess);
202 }
203 //Else other command failed
204 else
205 {
206 CommandComplete(PVMFFailure);
207 }
208 }
209 }
210
211 i2Way->CheckRecordFileState();
212 }
213
DatapathError()214 void CPV2WayRecDatapath::DatapathError()
215 {
216 SetCmd(NULL);
217 }
218
219
ParentIsClosing()220 bool CPV2WayRecDatapath::ParentIsClosing()
221 {
222 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayRecDatapath::ParentIsClosing path state %d\n", iState));
223 return SetCmd(NULL);
224 }
225 #endif
226
227