]> git.vomp.tv Git - vompclient.git/blob - recinfo.cc
Improve connection failure handling
[vompclient.git] / recinfo.cc
1 /*
2     Copyright 2019 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20 //portions from vdr by Klaus Schmiding HSMF code
21
22 #include <math.h>
23
24 #include "log.h"
25 #include "i18n.h"
26
27 #include "recinfo.h"
28
29 static const char* TAG = "RecInfo";
30
31 RecInfo::RecInfo()
32 {
33   timerStart = 0;
34   timerEnd = 0;
35   resumePoint = 0;
36   summary = NULL;
37
38   numComponents = 0;
39   streams = NULL;
40   types = NULL;
41   languages = NULL;
42   descriptions = NULL;
43
44   title = NULL;
45
46   channelName = NULL;
47   duration = 0;
48   fileSize = 0;
49   priority = 0;
50   lifetime = 0;
51
52   summaryWithDetails = NULL;
53 }
54
55 RecInfo::~RecInfo()
56 {
57   LogNT::getInstance()->info(TAG, "Deleting recinfo: {}, {}", numComponents, summary);
58
59   if (summary) delete[] summary;
60
61   for (ULONG i = 0; i < numComponents; i++)
62   {
63     LogNT::getInstance()->info(TAG, "i: {}, languages[i]={:p}:{}", i, (void*)languages[i], languages[i]);
64     LogNT::getInstance()->info(TAG, "i: {}, descripti[i]={:p}:{}", i, (void*)descriptions[i], descriptions[i]);
65     if (languages[i]) delete[] (languages[i]);
66     if (descriptions[i]) delete[] (descriptions[i]);
67   }
68
69   if (numComponents)
70   {
71     delete[] languages;
72     delete[] descriptions;
73
74     delete[] streams;
75     delete[] types;
76   }
77
78   if (title) delete [] title;
79
80   timerStart = 0;
81   timerEnd = 0;
82   resumePoint = 0;
83   summary = NULL;
84
85   numComponents = 0;
86   streams = NULL;
87   types = NULL;
88   languages = NULL;
89   descriptions = NULL;
90
91   // TODO: Investigate why this is clearing instance vars
92
93   if (channelName) delete[] channelName;
94   channelName = NULL;
95   duration = 0;
96   fileSize = 0;
97   priority = 0;
98   lifetime = 0;
99
100   if (summaryWithDetails) delete[] summaryWithDetails;
101   summaryWithDetails = NULL;
102 }
103
104 void RecInfo::setNumComponents(ULONG tnumComponents)
105 {
106   numComponents = tnumComponents;
107   languages = new char*[numComponents];
108   descriptions = new char*[numComponents];
109   streams = new UCHAR[numComponents];
110   types = new UCHAR[numComponents];
111 }
112
113 void RecInfo::addComponent(ULONG componentNum, UCHAR tstream, UCHAR ttype, char* tlanguage, char* tdescription)
114 {
115   if (componentNum >= numComponents) return;
116   streams[componentNum] = tstream;
117   types[componentNum] = ttype;
118   languages[componentNum] = tlanguage;
119   descriptions[componentNum] = tdescription;
120 }
121
122 void RecInfo::print()
123 {
124   LogNT* logger = LogNT::getInstance();
125
126   logger->info(TAG, "timerStart {}", timerStart);
127   logger->info(TAG, "timerEnd {}", timerEnd);
128   logger->info(TAG, "resumePoint {}", resumePoint);
129   logger->info(TAG, "Summary: {}", summary);
130   logger->info(TAG, "numComponents: {}", numComponents);
131
132   for (ULONG i = 0; i < numComponents; i++)
133   {
134     logger->info(TAG, "streams[{}]: {}", i, streams[i]);
135     logger->info(TAG, "types[{}]: {}", i, types[i]);
136     logger->info(TAG, "languages[{}]: {}", i, languages[i]);
137     logger->info(TAG, "descriptions[{}]: {}", i, descriptions[i]);
138   }
139
140   logger->info(TAG, "Title: {}", title);
141   logger->info(TAG, "Channel: {}", channelName);
142   logger->info(TAG, "Duration: {}", duration);
143   logger->info(TAG, "Filesize: {}", fileSize);
144   logger->info(TAG, "Priority: {}", priority);
145   logger->info(TAG, "Lifetime: {}", lifetime);
146 }
147
148 bool RecInfo::hasNoVideo()
149 {
150   // If no info (numComponents == 0) assume there is video
151   if (!numComponents) return false;
152
153   // video = 1, audio = 2
154
155   for (ULONG i = 0; i < numComponents; i++)
156     if (streams[i] == 1) return false;
157
158   return true;
159 }
160
161 char* RecInfo::buildSummaryWithDetails(bool forceRefresh)
162 {
163   if (!summaryWithDetails || forceRefresh)
164   {
165     if (forceRefresh && summaryWithDetails) delete[] summaryWithDetails;
166
167     LogNT* logger = LogNT::getInstance();
168
169     int swdLength = strlen(summary) +
170                     strlen(tr("Channel: ")) + strlen(channelName) +
171                     strlen(tr("Duration: ")) + 5 + /* 'hh:mm' */
172                     strlen(tr("Resume at: ")) + 5 + /* 'hh:mm' */
173                     strlen(tr("Size: ")) + 8 + /* '12345 MB' */
174                     6 + /* line endings */
175                     40 /* just in case (translation of New?) */ ;
176
177     int mins = duration / 60;
178     int hours = mins / 60;
179     mins = mins % 60;
180
181
182     char resumePointText[30];
183     if (resumePoint == 0)
184     {
185       strncpy(resumePointText, tr("New"), 30);
186       resumePointText[29] = '\0';
187     }
188     else
189     {
190       hmsf resumeHMSF = framesToHMSF(resumePoint);
191       SNPRINTF(resumePointText, 30, "%01u:%02u", resumeHMSF.hours, resumeHMSF.minutes);
192     }
193
194     summaryWithDetails = new char[swdLength];
195     SNPRINTF(summaryWithDetails, swdLength, "%s\n\n%s%s\n%s%01i:%02i\n%s%s\n%s%lu MB", summary,
196              tr("Channel: "), channelName,
197              tr("Duration: "), hours, mins,
198              tr("Resume at: "), resumePointText,
199              tr("Size: "), fileSize
200             );
201
202     logger->info(TAG, "Build summary with details C: {}, A: {}", swdLength, strlen(summaryWithDetails));
203   }
204   return summaryWithDetails;
205 }
206
207 hmsf RecInfo::framesToHMSF(ULONG frames)
208 {
209   hmsf ret;
210   /* from vdr */
211   double Seconds;
212   ret.frames = int(modf((frames + 0.5) / fps, &Seconds) * fps + 1);
213   int s = int(Seconds);
214   ret.seconds = s % 60;
215   ret.minutes = s / 60 % 60;
216   ret.hours = s / 3600;
217
218   return ret;
219 }