~phablet-team/aethercast/fix-for-microsoft-dongle

« back to all changes in this revision

Viewing changes to src/mcs/video/videoformat.cpp

Add hardware encoding and video streaming support.

The hardware encoding is currently only for Android 5.x based devices. On all others encoding will simply not work. The streaming part of aethercast (MPEGTS packetizing, RTP sending) as based on some code from Android.

Approved by PS Jenkins bot, Thomas Voß, Jim Hodapp.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2016 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 */
 
17
 
 
18
#include "mcs/video/videoformat.h"
 
19
#include "mcs/logger.h"
 
20
 
 
21
namespace mcs {
 
22
namespace video {
 
23
 
 
24
std::string ResolutionTypeToString(wds::ResolutionType type) {
 
25
    switch (type) {
 
26
    case wds::CEA:
 
27
        return "CEA";
 
28
    case wds::VESA:
 
29
        return "VESA";
 
30
    case wds::HH:
 
31
        return "HH";
 
32
    default:
 
33
        break;
 
34
    }
 
35
    return "unknown";
 
36
}
 
37
 
 
38
std::string CEARatesAndResolutionsToString(wds::CEARatesAndResolutions type) {
 
39
    switch (type) {
 
40
    case wds::CEA640x480p60:
 
41
        return "640x480p60";
 
42
    case wds::CEA720x480p60:
 
43
        return "720x480p60";
 
44
    case wds::CEA720x480i60:
 
45
        return "720x480i60";
 
46
    case wds::CEA720x576p50:
 
47
        return "720x576p50";
 
48
    case wds::CEA720x576i50:
 
49
        return "720x576i50";
 
50
    case wds::CEA1280x720p30:
 
51
        return "1280x720p30";
 
52
    case wds::CEA1280x720p60:
 
53
        return "1280x720p60";
 
54
    case wds::CEA1920x1080p30:
 
55
        return "1920x1080p30";
 
56
    case wds::CEA1920x1080p60:
 
57
        return "1920x1080p60";
 
58
    case wds::CEA1920x1080i60:
 
59
        return "1920x1080i60";
 
60
    case wds::CEA1280x720p25:
 
61
        return "1280x720p25";
 
62
    case wds::CEA1280x720p50:
 
63
        return "1280x720p50";
 
64
    case wds::CEA1920x1080p25:
 
65
        return "1920x1080p25";
 
66
    case wds::CEA1920x1080p50:
 
67
        return "1920x1080p50";
 
68
    case wds::CEA1920x1080i50:
 
69
        return "1920x1080i50";
 
70
    case wds::CEA1280x720p24:
 
71
        return "1280x720p24";
 
72
    case wds::CEA1920x1080p24:
 
73
        return "1920x1080p24";
 
74
    default:
 
75
        break;
 
76
    }
 
77
    return "unknown";
 
78
}
 
79
 
 
80
std::string VESARatesAndResolutionsToString(wds::VESARatesAndResolutions type) {
 
81
    switch (type) {
 
82
    case wds::VESA800x600p30:
 
83
        return "800x600p30";
 
84
    case wds::VESA800x600p60:
 
85
        return "800x600p60";
 
86
    case wds::VESA1024x768p30:
 
87
        return "1024x768p30";
 
88
    case wds::VESA1024x768p60:
 
89
        return "1024x768p60";
 
90
    case wds::VESA1152x864p30:
 
91
        return "1152x864p30";
 
92
    case wds::VESA1152x864p60:
 
93
        return "1152x864p60";
 
94
    case wds::VESA1280x768p30:
 
95
        return "1280x768p30";
 
96
    case wds::VESA1280x768p60:
 
97
        return "1280x768p60";
 
98
    case wds::VESA1280x800p30:
 
99
        return "1280x800p30";
 
100
    case wds::VESA1280x800p60:
 
101
        return "1280x800p60";
 
102
    case wds::VESA1360x768p30:
 
103
        return "1360x768p30";
 
104
    case wds::VESA1360x768p60:
 
105
        return "1360x768p60";
 
106
    case wds::VESA1366x768p30:
 
107
        return "1366x768p30";
 
108
    case wds::VESA1366x768p60:
 
109
        return "1366x768p60";
 
110
    case wds::VESA1280x1024p30:
 
111
        return "1280x1024p30";
 
112
    case wds::VESA1280x1024p60:
 
113
        return "1280x1024p60";
 
114
    case wds::VESA1400x1050p30:
 
115
        return "1400x1050p30";
 
116
    case wds::VESA1400x1050p60:
 
117
        return "1400x1050p60";
 
118
    case wds::VESA1440x900p30:
 
119
        return "1440x900p30";
 
120
    case wds::VESA1440x900p60:
 
121
        return "1440x900p60";
 
122
    case wds::VESA1600x900p30:
 
123
        return "1600x900p30";
 
124
    case wds::VESA1600x900p60:
 
125
        return "1600x900p60";
 
126
    case wds::VESA1600x1200p30:
 
127
        return "1600x1200p30";
 
128
    case wds::VESA1600x1200p60:
 
129
        return "1600x1200p60";
 
130
    case wds::VESA1680x1024p30:
 
131
        return "1680x1024p30";
 
132
    case wds::VESA1680x1024p60:
 
133
        return "1680x1024p60";
 
134
    case wds::VESA1680x1050p30:
 
135
        return "1680x1050p30";
 
136
    case wds::VESA1680x1050p60:
 
137
        return "1680x1050p60";
 
138
    case wds::VESA1920x1200p30:
 
139
        return "1920x1200p30";
 
140
    default:
 
141
        break;
 
142
    }
 
143
    return "unknown";
 
144
}
 
145
 
 
146
std::string HHRatesAndResolutionsToString(wds::HHRatesAndResolutions type) {
 
147
    switch (type) {
 
148
    case wds::HH800x480p30:
 
149
      return "800x480p30";
 
150
    case wds::HH800x480p60:
 
151
      return "800x480p60";
 
152
    case wds::HH854x480p30:
 
153
      return "854x480p30";
 
154
    case wds::HH854x480p60:
 
155
      return "854x480p60";
 
156
    case wds::HH864x480p30:
 
157
      return "864x480p30";
 
158
    case wds::HH864x480p60:
 
159
      return "864x480p60";
 
160
    case wds::HH640x360p30:
 
161
      return "640x360p30";
 
162
    case wds::HH640x360p60:
 
163
      return "640x360p60";
 
164
    case wds::HH960x540p30:
 
165
      return "960x540p30";
 
166
    case wds::HH960x540p60:
 
167
      return "960x540p60";
 
168
    case wds::HH848x480p30:
 
169
      return "848x480p30";
 
170
    case wds::HH848x480p60:
 
171
      return "848x480p60";
 
172
    default:
 
173
        break;
 
174
    }
 
175
    return "unknown";
 
176
}
 
177
 
 
178
std::string LevelToString(wds::H264Level level) {
 
179
    switch (level) {
 
180
    case wds::k3_1:
 
181
        return "3.1";
 
182
    case wds::k3_2:
 
183
        return "3.2";
 
184
    case wds::k4:
 
185
        return "4";
 
186
    case wds::k4_1:
 
187
        return "4.1";
 
188
    case wds::k4_2:
 
189
        return "4.2";
 
190
    default:
 
191
        break;
 
192
    }
 
193
    return "unknown";
 
194
}
 
195
 
 
196
std::string ProfileToString(wds::H264Profile profile) {
 
197
    switch (profile) {
 
198
    case wds::CBP:
 
199
        return "cbp";
 
200
    case wds::CHP:
 
201
        return "chp";
 
202
    default:
 
203
        break;
 
204
    }
 
205
    return "unknown";
 
206
}
 
207
 
 
208
void DumpVideoCodec(const wds::H264VideoCodec &codec) {
 
209
    int i = 0;
 
210
 
 
211
    DEBUG(" profile: %s", ProfileToString(codec.profile));
 
212
    DEBUG(" level: %s", LevelToString(codec.level));
 
213
 
 
214
    DEBUG(" CEA resolutions: ");
 
215
    for (i = wds::CEA640x480p60; i <= wds::CEA1920x1080p24; ++i)
 
216
        if (codec.cea_rr.test(i))
 
217
            DEBUG("  %s", CEARatesAndResolutionsToString((wds::CEARatesAndResolutions) i).c_str());
 
218
 
 
219
    DEBUG(" VESA resolutions: ");
 
220
    for (i = wds::VESA800x600p30; i <= wds::VESA1920x1200p30; ++i)
 
221
        if (codec.vesa_rr.test(i))
 
222
            DEBUG("  %s", VESARatesAndResolutionsToString((wds::VESARatesAndResolutions) i).c_str());
 
223
 
 
224
    DEBUG(" HH resolutions: ");
 
225
    for (i = wds::HH800x480p30; i <= wds::HH848x480p60; ++i)
 
226
        if (codec.hh_rr.test(i))
 
227
            DEBUG("  %s", HHRatesAndResolutionsToString((wds::HHRatesAndResolutions) i).c_str());
 
228
}
 
229
 
 
230
void DumpVideoFormat(const wds::H264VideoFormat &format) {
 
231
    DEBUG(" profile: %s", ProfileToString(format.profile));
 
232
    DEBUG(" level: %s", LevelToString(format.level));
 
233
    DEBUG(" resolution type: %s", ResolutionTypeToString(format.type));
 
234
 
 
235
    if (format.type == wds::CEA)
 
236
        DEBUG("resolution: %s", CEARatesAndResolutionsToString((wds::CEARatesAndResolutions) format.rate_resolution));
 
237
    if (format.type == wds::VESA)
 
238
        DEBUG("resolution: %s", VESARatesAndResolutionsToString((wds::VESARatesAndResolutions) format.rate_resolution));
 
239
    if (format.type == wds::HH)
 
240
        DEBUG("resolution: %s", HHRatesAndResolutionsToString((wds::HHRatesAndResolutions) format.rate_resolution));
 
241
}
 
242
 
 
243
void DumpNativeFormat(const wds::NativeVideoFormat &format) {
 
244
    DEBUG(" resolution type: %s", ResolutionTypeToString(format.type));
 
245
 
 
246
    if (format.type == wds::CEA)
 
247
        DEBUG("resolution: %s", CEARatesAndResolutionsToString((wds::CEARatesAndResolutions) format.rate_resolution));
 
248
    if (format.type == wds::VESA)
 
249
        DEBUG("resolution: %s", VESARatesAndResolutionsToString((wds::VESARatesAndResolutions) format.rate_resolution));
 
250
    if (format.type == wds::HH)
 
251
        DEBUG("resolution: %s", HHRatesAndResolutionsToString((wds::HHRatesAndResolutions) format.rate_resolution));
 
252
}
 
253
 
 
254
std::string ExtractH264Profile(const wds::H264VideoFormat &format) {
 
255
    std::string profile;
 
256
    switch (format.profile) {
 
257
    case wds::CBP:
 
258
        profile = "constrained-baseline";
 
259
        break;
 
260
    case wds::CHP:
 
261
        profile = "high";
 
262
        break;
 
263
    default:
 
264
        break;
 
265
    }
 
266
    return profile;
 
267
}
 
268
 
 
269
std::string ExtractH264Level(const wds::H264VideoFormat &format) {
 
270
    std::string level;
 
271
    switch (format.level) {
 
272
    case wds::k3_1:
 
273
        level = "3.1";
 
274
        break;
 
275
    case wds::k3_2:
 
276
        level = "3.2";
 
277
        break;
 
278
    case wds::k4:
 
279
        level = "4";
 
280
        break;
 
281
    case wds::k4_1:
 
282
        level = "4.1";
 
283
        break;
 
284
    case wds::k4_2:
 
285
        level = "4.2";
 
286
        break;
 
287
    default:
 
288
        break;
 
289
    }
 
290
    return level;
 
291
}
 
292
 
 
293
RateAndResolution ExtractRateAndResolution(const wds::H264VideoFormat &format) {
 
294
    RateAndResolution rr;
 
295
    switch (format.type) {
 
296
    case wds::CEA:
 
297
        switch (format.rate_resolution) {
 
298
        case wds::CEA640x480p60:
 
299
            rr.width = 640;
 
300
            rr.height = 480;
 
301
            rr.framerate = 60;
 
302
            break;
 
303
        case wds::CEA720x480p60:
 
304
        case wds::CEA720x480i60:
 
305
            rr.width = 720;
 
306
            rr.height = 480;
 
307
            rr.framerate = 60;
 
308
            break;
 
309
        case wds::CEA720x576p50:
 
310
        case wds::CEA720x576i50:
 
311
            rr.width = 720;
 
312
            rr.height = 576;
 
313
            rr.framerate = 50;
 
314
            break;
 
315
        case wds::CEA1280x720p30:
 
316
            rr.width = 1280;
 
317
            rr.height = 720;
 
318
            rr.framerate = 30;
 
319
            break;
 
320
        case wds::CEA1280x720p60:
 
321
            rr.width = 1280;
 
322
            rr.height = 720;
 
323
            rr.framerate = 60;
 
324
            break;
 
325
        case wds::CEA1920x1080p30:
 
326
            rr.width = 1920;
 
327
            rr.height = 1080;
 
328
            rr.framerate = 30;
 
329
            break;
 
330
        case wds::CEA1920x1080p60:
 
331
        case wds::CEA1920x1080i60:
 
332
            rr.width = 1920;
 
333
            rr.height = 1080;
 
334
            rr.framerate = 60;
 
335
            break;
 
336
        case wds::CEA1280x720p25:
 
337
            rr.width = 1280;
 
338
            rr.height = 720;
 
339
            rr.framerate = 25;
 
340
            break;
 
341
        case wds::CEA1280x720p50:
 
342
            rr.width = 1280;
 
343
            rr.height = 720;
 
344
            rr.framerate = 50;
 
345
            break;
 
346
        case wds::CEA1280x720p24:
 
347
            rr.width = 1280;
 
348
            rr.height = 720;
 
349
            rr.framerate = 24;
 
350
            break;
 
351
        case wds::CEA1920x1080p25:
 
352
            rr.width = 1920;
 
353
            rr.height = 1080;
 
354
            rr.framerate = 25;
 
355
            break;
 
356
        case wds::CEA1920x1080p50:
 
357
            rr.width = 1920;
 
358
            rr.height = 1080;
 
359
            rr.framerate = 50;
 
360
            break;
 
361
        case wds::CEA1920x1080i50:
 
362
            rr.width = 1920;
 
363
            rr.height = 1080;
 
364
            rr.framerate = 50;
 
365
            break;
 
366
        case wds::CEA1920x1080p24:
 
367
            rr.width = 1920;
 
368
            rr.height = 1080;
 
369
            rr.framerate = 24;
 
370
            break;
 
371
        default:
 
372
            break;
 
373
        }
 
374
        break;
 
375
    // FIXME Add support for VESA and HH
 
376
    default:
 
377
        rr.width = 640;
 
378
        rr.height = 480;
 
379
        rr.framerate = 30;
 
380
        break;
 
381
    }
 
382
    return rr;
 
383
}
 
384
 
 
385
void ExtractProfileLevel(const wds::H264VideoFormat &format, int *profile,
 
386
                            int *level, int *constraint) {
 
387
 
 
388
    if (format.profile == wds::CBP) {
 
389
        *profile = 66;
 
390
        *constraint = 0xc0;
 
391
    }
 
392
    else if (format.profile == wds::CHP) {
 
393
        *profile = 100;
 
394
        *constraint = 0x0c;
 
395
    }
 
396
 
 
397
    switch (format.level) {
 
398
    case wds::k3_1:
 
399
        *level = 31;
 
400
        break;
 
401
    case wds::k3_2:
 
402
        *level = 32;
 
403
        break;
 
404
    case wds::k4:
 
405
        *level = 40;
 
406
        break;
 
407
    case wds::k4_1:
 
408
        *level = 41;
 
409
        break;
 
410
    case wds::k4_2:
 
411
        *level = 42;
 
412
    }
 
413
}
 
414
 
 
415
} // namespace video
 
416
} // namespace mcs