[M120 Migration] Build libchromium-impl.so with chrome implementation
[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   std::string app_id =
223       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
224           switches::kTizenAppId);
225
226   // resource center returns decodeer ability not resolution (ex.1088)
227   // http://wiki.vd.sec.samsung.net/display/OSS/02.+Max+Resolution
228   if (rc_get_max_video_resolution(app_id.c_str(), &max_width, &max_height,
229                                   &max_framerate) < 0) {
230     LOG(ERROR) << "Getting max video resolution failed in multiview mode.";
231     return {kFHDVideoMaxWidth, kFHDVideoMaxHeight};
232   }
233
234   // H.264 has to be decoded by 4K decoder(dvde) in multiview mode
235   // to support below scenario.
236   // Left FHD@30 (TVPlus) | Right FHD@60 (AirPlay is placed at right always)
237   // Refer to http://wiki.vd.sec.samsung.net/display/OSS/10.+Resource+table
238   if (max_width >= k8KVideoMaxWidth) {
239     return k8KVideoMaxSize;
240   } else if (max_width >= k4KVideoMaxWidth && max_width < k8KVideoMaxWidth) {
241     return k4KVideoMaxSize;
242   } else {
243     return kFHDVideoMaxSize;
244   }
245 }
246
247 const char* GetRIVideoCodecName(esplusplayer_video_mime_type mime_type) {
248   switch (mime_type) {
249     case ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1:
250       return RI_CODEC_NAME_AV1;
251     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8:
252       return RI_CODEC_NAME_VP8;
253     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9:
254       return RI_CODEC_NAME_VP9;
255     case ESPLUSPLAYER_VIDEO_MIME_TYPE_HEVC:
256       return RI_CODEC_NAME_HEVC;
257     case ESPLUSPLAYER_VIDEO_MIME_TYPE_H264:
258       return RI_CODEC_NAME_H264;
259     case ESPLUSPLAYER_VIDEO_MIME_TYPE_MJPEG:
260       return RI_CODEC_NAME_MJPEG;
261     default:
262       break;
263   }
264   return "";
265 }
266
267 gfx::Size GetMaxCodecResolutionRI(esplusplayer_video_mime_type mime_type,
268                                   bool is_video_hole) {
269   int max_width = 0;
270   int max_height = 0;
271   int max_framerate = 0;
272   const char* ri_video_codec = GetRIVideoCodecName(mime_type);
273
274   // In portrait mode adaptive streaming has some problem
275   // when changing a resolution so Sero uses dvde decoder
276   // for all kind of codecs.
277   // The dvde decoder doesn't support VP8 and WMV. It is Sero product spec.
278   if (!*ri_video_codec) {
279     if (isProductTypeSero()) {
280       return k4KVideoMaxSize;
281     } else {
282       return kFHDVideoMaxSize;
283     }
284   }
285
286   if (ri_video_codec == RI_CODEC_NAME_H264) {
287     if (is_video_hole && isProductTypeSero())
288       return k4KVideoMaxSize;
289     else
290       return kFHDVideoMaxSize;
291   }
292
293   if (ri_get_max_resolution(ri_video_codec, &max_width, &max_height,
294                             &max_framerate) != RI_OK) {
295     LOG(WARNING) << "Failed to get video max information";
296     const auto panel_resolution = GetPanelResolution();
297     return {panel_resolution.width(), panel_resolution.height()};
298   }
299
300   if (max_width >= k8KVideoMaxWidth) {
301     max_width = k8KVideoMaxWidth;
302     max_height = k8KVideoMaxHeight;
303   } else if (max_width >= k4KVideoMaxWidth && max_width < k8KVideoMaxWidth) {
304     max_width = k4KVideoMaxWidth;
305     max_height = k4KVideoMaxHeight;
306   } else if (max_width >= kFHDVideoMaxWidth && max_width < k4KVideoMaxWidth) {
307     max_width = kFHDVideoMaxWidth;
308     max_height = kFHDVideoMaxHeight;
309   }
310   return {max_width, max_height};
311 }
312 #endif
313
314 gfx::Size GetMaxCodecResolution(esplusplayer_video_mime_type mime_type,
315                                 bool is_video_hole) {
316 #if BUILDFLAG(IS_TIZEN_TV) && TIZEN_VERSION_AT_LEAST(6, 0, 0)
317   if (media::IsMultiviewMode()) {
318     // Multiview specification:
319     // http://wiki.vd.sec.samsung.net/pages/viewpage.action?pageId=79211942
320     return GetDynamicMaxCodecResolution();
321   }
322   return GetMaxCodecResolutionRI(mime_type, is_video_hole);
323 #else
324   switch (mime_type) {
325     case ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1:
326     case ESPLUSPLAYER_VIDEO_MIME_TYPE_HEVC:
327     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9:
328       return k8KVideoMaxSize;
329     case ESPLUSPLAYER_VIDEO_MIME_TYPE_H264:
330       // H.264 has to be decoded by dvde decoder in multiview mode
331       // to support below scenario.
332       // Left FHD@30 (TVPlus) | Right FHD@60 (AirPlay)
333       // Refer to http://wiki.vd.sec.samsung.net/display/OSS/10.+Resource+table
334       if (is_video_hole && isProductTypeSero())
335         return k4KVideoMaxSize;
336       else
337         return kFHDVideoMaxSize;
338     case ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8:
339     default:
340       // In portrait mode adaptive streaming has some problem
341       // when changing a resolution so Sero uses dvde decoder
342       // for all kind of codecs.
343       // The dvde decoder doesn't support VP8 and WMV. It is Sero product spec.
344       if (isProductTypeSero())
345         return k4KVideoMaxSize;
346       else
347         return kFHDVideoMaxSize;
348   }
349 #endif
350 }
351
352 gfx::Size GetPanelResolution() {
353   gfx::Size panel_size;
354 #if BUILDFLAG(IS_TIZEN_TV)
355   panel_size = gfx::Size(GetTVPanelWidth(), GetTVPanelHeight());
356 #endif
357   return panel_size.IsEmpty() ? kFHDVideoMaxSize : panel_size;
358 }
359
360 gfx::Size GetMaxResolution(esplusplayer_video_mime_type mime_type,
361                            bool is_video_hole) {
362   const auto max_codec_resolution =
363       GetMaxCodecResolution(mime_type, is_video_hole);
364   const auto panel_resolution = GetPanelResolution();
365   return {std::min(max_codec_resolution.width(), panel_resolution.width()),
366           std::min(max_codec_resolution.height(), panel_resolution.height())};
367 }
368
369 esplusplayer_display_rotation_type ConvertToESPlusPlayerDisplayRotation(
370     int rotation) {
371   switch (rotation) {
372     case 90:
373       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_270;
374     case 180:
375       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_180;
376     case 270:
377       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_90;
378     default:
379       return ESPLUSPLAYER_DISPLAY_ROTATION_TYPE_NONE;
380   }
381 }
382
383 #if BUILDFLAG(IS_TIZEN_TV)
384 bool IsMultiviewMode() {
385   const char vconf_multiview_info[] = "memory/multiscreen/info";
386
387   char* multiview_info = vconf_get_str(vconf_multiview_info);
388   if (multiview_info) {
389     auto multiview_info_value = base::JSONReader::Read(multiview_info);
390     free(multiview_info);
391     if (!multiview_info_value || !multiview_info_value->is_dict()) {
392       LOG(ERROR) << "read vconf multiview info failed";
393       return false;
394     }
395
396     base::Value::Dict& dict = multiview_info_value->GetDict();
397
398     const std::string* mode_value = dict.FindString("mode");
399     if (mode_value && *mode_value == "on") {
400       LOG(INFO) << "It is in multiview mode.";
401       return true;
402     }
403   }
404
405   return false;
406 }
407 #endif
408
409 }  // namespace media