fixup! [M120 Migration] Add new api for webbrowser to get media device list
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / media / filters / esplusplayer_util.cc
1 // Copyright 2022 Samsung Electronics Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "tizen_src/chromium_impl/media/filters/esplusplayer_util.h"
6
7 #include <vconf/vconf.h>
8
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "tizen_src/chromium_impl/build/tizen_version.h"
12
13 #if BUILDFLAG(IS_TIZEN_TV)
14 #include <resource_center.h>
15 #include <ri-common-type.h>
16 #include <ri-module-api.h>
17 #include <tv-resource-information/ri-api.h>
18 #include <tv-resource-manager/rm_module_api.h>
19 #include "base/command_line.h"
20 #include "base/memory/ptr_util.h"
21 #include "content/public/common/content_switches.h"
22 #include "ewk/efl_integration/common/application_type.h"
23 #include "ewk/efl_integration/common/content_switches_efl.h"
24 #include "tizen_src/chromium_impl/tizen/tizen_tv_platform.h"
25 #endif
26
27 namespace {
28
29 #define ENUM_CASE(x) \
30   case x:            \
31     return #x;       \
32     break
33
34 }  // namespace
35
36 constexpr gfx::Size kFHDVideoMaxSize(1920, 1080);
37 constexpr gfx::Size k4KVideoMaxSize(3840, 2160);
38 constexpr gfx::Size k8KVideoMaxSize(7680, 4320);
39
40 namespace media {
41
42 const char* GetString(media::BufferStatus status) {
43   switch (status) {
44     ENUM_CASE(media::kBufferNone);
45     ENUM_CASE(media::kBufferUnderrun);
46     ENUM_CASE(media::kBufferMinThreshold);
47     ENUM_CASE(media::kBufferNormal);
48     ENUM_CASE(media::kBufferMaxThreshold);
49     ENUM_CASE(media::kBufferOverflow);
50     ENUM_CASE(media::kBufferAhead);
51     ENUM_CASE(media::kBufferEos);
52   };
53   NOTREACHED() << "Invalid BufferStatus (" << status << ")";
54   return "";
55 }
56
57 const char* GetString(esplusplayer_submit_status status) {
58   switch (status) {
59     ENUM_CASE(ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED);
60     ENUM_CASE(ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET);
61     ENUM_CASE(ESPLUSPLAYER_SUBMIT_STATUS_OUT_OF_MEMORY);
62     ENUM_CASE(ESPLUSPLAYER_SUBMIT_STATUS_FULL);
63     ENUM_CASE(ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS);
64   };
65   NOTREACHED() << "Invalid Submit Status (" << status << ")";
66   return "";
67 }
68
69 const char* GetString(esplusplayer_state state) {
70   switch (state) {
71     ENUM_CASE(ESPLUSPLAYER_STATE_NONE);
72     ENUM_CASE(ESPLUSPLAYER_STATE_IDLE);
73     ENUM_CASE(ESPLUSPLAYER_STATE_READY);
74     ENUM_CASE(ESPLUSPLAYER_STATE_PLAYING);
75     ENUM_CASE(ESPLUSPLAYER_STATE_PAUSED);
76     ENUM_CASE(ESPLUSPLAYER_STATE_MAX);
77   };
78   NOTREACHED() << "Invalid state (" << state << ")";
79   return "";
80 }
81
82 esplusplayer_audio_mime_type ConvertToESPlusAudioMimeType(
83     media::AudioCodec codec) {
84   esplusplayer_audio_mime_type audioMimeType;
85   switch (codec) {
86     case media::AudioCodec::kAAC:
87       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_AAC;
88       break;
89     case media::AudioCodec::kMP3:
90       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_MP3;
91       break;
92     case media::AudioCodec::kOpus:
93       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_OPUS;
94       break;
95     case media::AudioCodec::kPCM:
96       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_PCM_S16LE;
97       break;
98     case media::AudioCodec::kVorbis:
99       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_VORBIS;
100       break;
101     case media::AudioCodec::kEAC3:
102       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_EAC3;
103       break;
104     case media::AudioCodec::kAC3:
105       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_AC3;
106       break;
107 #if BUILDFLAG(IS_TIZEN_TV) && TIZEN_VERSION_AT_LEAST(8, 0, 0)
108     case media::AudioCodec::kFLAC:
109       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_FLAC;
110       break;
111 #endif
112     default: {
113       LOG(WARNING) << "Unknown codec :" << codec << ". Returning MP3.";
114       audioMimeType = ESPLUSPLAYER_AUDIO_MIME_TYPE_MP3;
115     }
116   }
117   return audioMimeType;
118 }
119
120 esplusplayer_video_mime_type ConvertToESPlusVideoMimeType(
121     media::VideoCodec codec) {
122   esplusplayer_video_mime_type videoMimeType;
123   switch (codec) {
124     case media::VideoCodec::kH264:
125       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_H264;
126       break;
127     case media::VideoCodec::kMPEG2:
128       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_MPEG2;
129       break;
130     case media::VideoCodec::kMPEG4:
131       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_MPEG4;
132       break;
133     case media::VideoCodec::kVP8:
134       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8;
135       break;
136     case media::VideoCodec::kVP9:
137       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9;
138       break;
139     case media::VideoCodec::kHEVC:
140       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_HEVC;
141       break;
142     case media::VideoCodec::kAV1:
143       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1;
144       break;
145     default: {
146       LOG(WARNING) << "Unknown codec :" << codec << ". Returning H264.";
147       videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_H264;
148     }
149   }
150   return videoMimeType;
151 }
152
153 int GetElementryStreamIndex(DemuxerStream::Type type) {
154   DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
155
156   switch (type) {
157     case DemuxerStream::AUDIO:
158       return 0;
159     case DemuxerStream::VIDEO:
160       return 1;
161     default:
162       LOG(ERROR) << "Stream type [" << type
163                  << "] is not supported. Returning 0 (Audio type).";
164       return 0;
165   }
166 }
167
168 DemuxerStream::Type GetDemuxerStreamType(
169     const esplusplayer_stream_type stream_type) {
170   switch (stream_type) {
171     case ESPLUSPLAYER_STREAM_TYPE_AUDIO:
172       return DemuxerStream::AUDIO;
173     case ESPLUSPLAYER_STREAM_TYPE_VIDEO:
174       return DemuxerStream::VIDEO;
175     default:
176       return DemuxerStream::UNKNOWN;
177   }
178 }
179
180 esplusplayer_stream_type GetESPlusPlayerStreamType(DemuxerStream::Type type) {
181   switch (type) {
182     case DemuxerStream::AUDIO:
183       return ESPLUSPLAYER_STREAM_TYPE_AUDIO;
184     case DemuxerStream::VIDEO:
185       return ESPLUSPLAYER_STREAM_TYPE_VIDEO;
186     default:
187       return ESPLUSPLAYER_STREAM_TYPE_MAX;
188   }
189 }
190
191 PipelineStatus GetPipelineError(const esplusplayer_error_type error) {
192   if (error == ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC ||
193       error == ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC ||
194       error == ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT ||
195       error == ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE)
196     return DECODER_ERROR_NOT_SUPPORTED;
197   else if (error == ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE)
198     return PIPELINE_ERROR_INVALID_STATE;
199   else if (error == ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY)
200     return PIPELINE_ERROR_ABORT;
201   else if (error == ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED)
202     return PIPELINE_ERROR_NETWORK;
203
204   return PIPELINE_ERROR_DECODE;
205 }
206
207 bool isProductTypeSero() {
208   bool is_sero = false;
209 #if BUILDFLAG(IS_TIZEN_TV)
210   is_sero = isTVRotated();
211 #endif
212
213   LOG(INFO) << "This product type is " << (is_sero ? "a Sero" : "not a Sero");
214   return is_sero;
215 }
216
217 #if BUILDFLAG(IS_TIZEN_TV) && TIZEN_VERSION_AT_LEAST(6, 0, 0)
218 gfx::Size GetDynamicMaxCodecResolution() {
219   int max_width = 0;
220   int max_height = 0;
221   int max_framerate = 0;
222 #if !defined(BUILD_CHROME)
223   std::string app_id =
224       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
225           switches::kTizenAppId);
226 #else
227   std::string app_id = "";
228 #endif
229
230   // resource center returns decodeer ability not resolution (ex.1088)
231   // http://wiki.vd.sec.samsung.net/display/OSS/02.+Max+Resolution
232   if (rc_get_max_video_resolution(app_id.c_str(), &max_width, &max_height,
233                                   &max_framerate) < 0) {
234     LOG(ERROR) << "Getting max video resolution failed in multiview mode.";
235     return {kFHDVideoMaxWidth, kFHDVideoMaxHeight};
236   }
237
238   // H.264 has to be decoded by 4K decoder(dvde) in multiview mode
239   // to support below scenario.
240   // Left FHD@30 (TVPlus) | Right FHD@60 (AirPlay is placed at right always)
241   // Refer to http://wiki.vd.sec.samsung.net/display/OSS/10.+Resource+table
242   if (max_width >= k8KVideoMaxWidth) {
243     return k8KVideoMaxSize;
244   } else if (max_width >= k4KVideoMaxWidth && max_width < k8KVideoMaxWidth) {
245     return k4KVideoMaxSize;
246   } else {
247     return kFHDVideoMaxSize;
248   }
249 }
250
251 const char* GetRIVideoCodecName(esplusplayer_video_mime_type mime_type) {
252   switch (mime_type) {
253     case ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1:
254       return RI_CODEC_NAME_AV1;
255     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8:
256       return RI_CODEC_NAME_VP8;
257     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9:
258       return RI_CODEC_NAME_VP9;
259     case ESPLUSPLAYER_VIDEO_MIME_TYPE_HEVC:
260       return RI_CODEC_NAME_HEVC;
261     case ESPLUSPLAYER_VIDEO_MIME_TYPE_H264:
262       return RI_CODEC_NAME_H264;
263     case ESPLUSPLAYER_VIDEO_MIME_TYPE_MJPEG:
264       return RI_CODEC_NAME_MJPEG;
265     default:
266       break;
267   }
268   return "";
269 }
270
271 gfx::Size GetMaxCodecResolutionRI(esplusplayer_video_mime_type mime_type,
272                                   bool is_video_hole) {
273   int max_width = 0;
274   int max_height = 0;
275   int max_framerate = 0;
276   const char* ri_video_codec = GetRIVideoCodecName(mime_type);
277
278   // In portrait mode adaptive streaming has some problem
279   // when changing a resolution so Sero uses dvde decoder
280   // for all kind of codecs.
281   // The dvde decoder doesn't support VP8 and WMV. It is Sero product spec.
282   if (!*ri_video_codec) {
283     if (isProductTypeSero()) {
284       return k4KVideoMaxSize;
285     } else {
286       return kFHDVideoMaxSize;
287     }
288   }
289
290   if (ri_video_codec == RI_CODEC_NAME_H264) {
291     if (is_video_hole && isProductTypeSero())
292       return k4KVideoMaxSize;
293     else
294       return kFHDVideoMaxSize;
295   }
296
297   if (ri_get_max_resolution(ri_video_codec, &max_width, &max_height,
298                             &max_framerate) != RI_OK) {
299     LOG(WARNING) << "Failed to get video max information";
300     const auto panel_resolution = GetPanelResolution();
301     return {panel_resolution.width(), panel_resolution.height()};
302   }
303
304   if (max_width >= k8KVideoMaxWidth) {
305     max_width = k8KVideoMaxWidth;
306     max_height = k8KVideoMaxHeight;
307   } else if (max_width >= k4KVideoMaxWidth && max_width < k8KVideoMaxWidth) {
308     max_width = k4KVideoMaxWidth;
309     max_height = k4KVideoMaxHeight;
310   } else if (max_width >= kFHDVideoMaxWidth && max_width < k4KVideoMaxWidth) {
311     max_width = kFHDVideoMaxWidth;
312     max_height = kFHDVideoMaxHeight;
313   }
314   return {max_width, max_height};
315 }
316 #endif
317
318 gfx::Size GetMaxCodecResolution(esplusplayer_video_mime_type mime_type,
319                                 bool is_video_hole) {
320 #if BUILDFLAG(IS_TIZEN_TV) && TIZEN_VERSION_AT_LEAST(6, 0, 0)
321   if (media::IsMultiviewMode()) {
322     // Multiview specification:
323     // http://wiki.vd.sec.samsung.net/pages/viewpage.action?pageId=79211942
324     return GetDynamicMaxCodecResolution();
325   }
326   return GetMaxCodecResolutionRI(mime_type, is_video_hole);
327 #else
328   switch (mime_type) {
329     case ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1:
330     case ESPLUSPLAYER_VIDEO_MIME_TYPE_HEVC:
331     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9:
332       return k8KVideoMaxSize;
333     case ESPLUSPLAYER_VIDEO_MIME_TYPE_H264:
334       // H.264 has to be decoded by dvde decoder in multiview mode
335       // to support below scenario.
336       // Left FHD@30 (TVPlus) | Right FHD@60 (AirPlay)
337       // Refer to http://wiki.vd.sec.samsung.net/display/OSS/10.+Resource+table
338       if (is_video_hole && isProductTypeSero())
339         return k4KVideoMaxSize;
340       else
341         return kFHDVideoMaxSize;
342     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8:
343     default:
344       // In portrait mode adaptive streaming has some problem
345       // when changing a resolution so Sero uses dvde decoder
346       // for all kind of codecs.
347       // The dvde decoder doesn't support VP8 and WMV. It is Sero product spec.
348       if (isProductTypeSero())
349         return k4KVideoMaxSize;
350       else
351         return kFHDVideoMaxSize;
352   }
353 #endif
354 }
355
356 gfx::Size GetPanelResolution() {
357   gfx::Size panel_size;
358 #if BUILDFLAG(IS_TIZEN_TV)
359   panel_size = gfx::Size(GetTVPanelWidth(), GetTVPanelHeight());
360 #endif
361   return panel_size.IsEmpty() ? kFHDVideoMaxSize : panel_size;
362 }
363
364 gfx::Size GetMaxResolution(esplusplayer_video_mime_type mime_type,
365                            bool is_video_hole) {
366   const auto max_codec_resolution =
367       GetMaxCodecResolution(mime_type, is_video_hole);
368   const auto panel_resolution = GetPanelResolution();
369   return {std::min(max_codec_resolution.width(), panel_resolution.width()),
370           std::min(max_codec_resolution.height(), panel_resolution.height())};
371 }
372
373 esplusplayer_display_rotation_type ConvertToESPlusPlayerDisplayRotation(
374     int rotation) {
375   switch (rotation) {
376     case 90:
377       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_270;
378     case 180:
379       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_180;
380     case 270:
381       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_90;
382     default:
383       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_NONE;
384   }
385 }
386
387 #if BUILDFLAG(IS_TIZEN_TV)
388 bool IsMultiviewMode() {
389   const char vconf_multiview_info[] = "memory/multiscreen/info";
390
391   char* multiview_info = vconf_get_str(vconf_multiview_info);
392   if (multiview_info) {
393     auto multiview_info_value = base::JSONReader::Read(multiview_info);
394     free(multiview_info);
395     if (!multiview_info_value || !multiview_info_value->is_dict()) {
396       LOG(ERROR) << "read vconf multiview info failed";
397       return false;
398     }
399
400     base::Value::Dict& dict = multiview_info_value->GetDict();
401
402     const std::string* mode_value = dict.FindString("mode");
403     if (mode_value && *mode_value == "on") {
404       LOG(INFO) << "It is in multiview mode.";
405       return true;
406     }
407   }
408
409   return false;
410 }
411 #endif
412
413 }  // namespace media