Steps to Reproduce
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
const _urls = [
'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1280_10MG.mp4',
'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_480_1_5MG.mp4',
'https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1920_18MG.mp4',
'https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4',
'https://samplelib.com/lib/download/mp4/sample-5s.mp4',
'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_30mb.mp4'
];
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp() : super(key: const ValueKey('MyApp'));
@override
Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatelessWidget {
const MyHomePage() : super(key: const ValueKey('MyHomePage'));
@override
Widget build(BuildContext context) => Material(
child: ListView.builder(
itemCount: _urls.length,
itemBuilder: (context, index) => MyWidget(index)),
);
}
class MyWidget extends StatefulWidget {
final int index;
MyWidget(this.index) : super(key: ValueKey('MyWidget: $index'));
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late final VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(_urls[widget.index])
..setLooping(true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<dynamic> _init() async {
await _controller.initialize();
return Null;
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _init(),
builder: (context, future) => !future.hasData
? const Align(child: CircularProgressIndicator())
: future.hasError
? const Align(child: Icon(Icons.error))
: GestureDetector(
onTap: () => _controller.value.isPlaying
? _controller.pause()
: _controller.play(),
child: Stack(
children: [
Align(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
),
Align(
child: Text(
'${widget.index}',
style: const TextStyle(color: Colors.orange),
textScaleFactor: 10,
),
)
],
),
),
);
}
}
Expected results:
All video players to be initialized correctly.
Actual results:
An initialization error happens in some Android devices. It works fine in Android emulator.
2 random videos out of 6 fail to load. The videos that fail to be loaded using the same code are not deterministic.
Logs
I/ExoPlayerImpl( 4308): Init aeb03ce [ExoPlayerLib/2.12.1] [nappa, Aquaris V, bq, 27]
I/zygote ( 4308): Do partial code cache collection, code=30KB, data=27KB
I/zygote ( 4308): After code cache collection, code=30KB, data=27KB
I/zygote ( 4308): Increasing code cache capacity to 128KB
W/VideoCapabilities( 4308): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities( 4308): Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities( 4308): Unsupported mime video/divx
W/VideoCapabilities( 4308): Unsupported mime video/divx4
W/Utils ( 4308): could not parse long range '146-132'
W/VideoCapabilities( 4308): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities( 4308): Unrecognized profile 2130706434 for video/avc
I/VideoCapabilities( 4308): Unsupported profile 4 for video/mp4v-es
W/VideoCapabilities( 4308): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities( 4308): Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities( 4308): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities( 4308): Unrecognized profile 2130706434 for video/avc
I/zygote ( 4308): Do partial code cache collection, code=53KB, data=51KB
I/zygote ( 4308): After code cache collection, code=53KB, data=51KB
I/zygote ( 4308): Increasing code cache capacity to 256KB
I/OMXClient( 4308): Treble IOmx obtained
I/OMXClient( 4308): Treble IOmx obtained
I/OMXClient( 4308): Treble IOmx obtained
D/SurfaceUtils( 4308): connecting to surface 0x8e8fd808, reason connectToSurface
I/MediaCodec( 4308): [OMX.qcom.video.decoder.avc] setting surface generation to 4411393
D/SurfaceUtils( 4308): disconnecting from surface 0x8e8fd808, reason connectToSurface(reconnect)
D/SurfaceUtils( 4308): connecting to surface 0x8e8fd808, reason connectToSurface(reconnect)
I/ExtendedACodec( 4308): setupVideoDecoder()
I/ExtendedACodec( 4308): Decoder will be in frame by frame mode
D/SurfaceUtils( 4308): connecting to surface 0x8c4c0808, reason connectToSurface
I/MediaCodec( 4308): [OMX.qcom.video.decoder.avc] setting surface generation to 4411394
D/SurfaceUtils( 4308): disconnecting from surface 0x8c4c0808, reason connectToSurface(reconnect)
D/SurfaceUtils( 4308): connecting to surface 0x8c4c0808, reason connectToSurface(reconnect)
I/ExtendedACodec( 4308): setupVideoDecoder()
I/ExtendedACodec( 4308): Decoder will be in frame by frame mode
D/SurfaceUtils( 4308): set up nativeWindow 0x8e8fd808 for 480x270, color 0x7fa30c04, rotation 0, usage 0x20002900
D/vndksupport( 4308): Loading /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
D/SurfaceUtils( 4308): connecting to surface 0x8860d808, reason connectToSurface
I/MediaCodec( 4308): [OMX.qcom.video.decoder.avc] setting surface generation to 4411395
D/SurfaceUtils( 4308): disconnecting from surface 0x8860d808, reason connectToSurface(reconnect)
D/SurfaceUtils( 4308): connecting to surface 0x8860d808, reason connectToSurface(reconnect)
D/vndksupport( 4308): Loading /vendor/lib/hw/gralloc.msm8937.so from current namespace instead of sphal namespace.
I/ExtendedACodec( 4308): setupVideoDecoder()
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
D/SurfaceUtils( 4308): set up nativeWindow 0x8c4c0808 for 1920x1080, color 0x7fa30c04, rotation 0, usage 0x20002900
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
I/ExtendedACodec( 4308): Decoder will be in frame by frame mode
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
I/OMXClient( 4308): Treble IOmx obtained
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
I/ACodec ( 4308): codec does not support config operating rate (err -2147483648)
W/ExtendedACodec( 4308): Failed to get extension for extradata parameter
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
I/OMXClient( 4308): Treble IOmx obtained
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
D/SurfaceUtils( 4308): set up nativeWindow 0x8e8fd808 for 480x272, color 0x7fa30c04, rotation 0, usage 0x20002900
D/SurfaceUtils( 4308): set up nativeWindow 0x8860d808 for 320x240, color 0x7fa30c04, rotation 0, usage 0x20002900
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/ExtendedACodec( 4308): Failed to get extension for extradata parameter
D/SurfaceUtils( 4308): set up nativeWindow 0x8c4c0808 for 1920x1088, color 0x7fa30c04, rotation 0, usage 0x20002900
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
I/OMXClient( 4308): Treble IOmx obtained
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
D/AudioTrack( 4308): Client defaulted notificationFrames to 7688 for frameCount 15376
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
D/SurfaceUtils( 4308): set up nativeWindow 0x8860d808 for 320x240, color 0x7fa30c04, rotation 0, usage 0x20002900
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
I/ACodec ( 4308): codec does not support config priority (err -2147483648)
I/ACodec ( 4308): codec does not support config operating rate (err -2147483648)
W/ExtendedACodec( 4308): Failed to get extension for extradata parameter
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
D/AudioTrack( 4308): Client defaulted notificationFrames to 4714 for frameCount 14144
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
W/GrallocMapperPassthrough( 4308): buffer descriptor with invalid usage bits 0x2000
D/AudioTrack( 4308): Client defaulted notificationFrames to 7688 for frameCount 15376
I/OMXClient( 4308): Treble IOmx obtained
D/SurfaceUtils( 4308): connecting to surface 0x886aa808, reason connectToSurface
I/MediaCodec( 4308): [OMX.qcom.video.decoder.avc] setting surface generation to 4411396
D/SurfaceUtils( 4308): disconnecting from surface 0x886aa808, reason connectToSurface(reconnect)
D/SurfaceUtils( 4308): connecting to surface 0x886aa808, reason connectToSurface(reconnect)
I/ExtendedACodec( 4308): setupVideoDecoder()
E/ACodec ( 4308): [OMX.qcom.video.decoder.avc] configureCodec returning error -12
E/ACodec ( 4308): signalError(omxError 0x80001001, internalError -12)
E/MediaCodec( 4308): Codec reported err 0xfffffff4, actionCode 0, while in state 3
D/SurfaceUtils( 4308): disconnecting from surface 0x886aa808, reason disconnectFromSurface
E/MediaCodec( 4308): configure failed with err 0xfffffff4, resetting...
I/OMXClient( 4308): Treble IOmx obtained
W/MediaCodecRenderer( 4308): Failed to initialize decoder: OMX.qcom.video.decoder.avc
W/MediaCodecRenderer( 4308): android.media.MediaCodec$CodecException: Error 0xfffffff4
W/MediaCodecRenderer( 4308): at android.media.MediaCodec.native_configure(Native Method)
W/MediaCodecRenderer( 4308): at android.media.MediaCodec.configure(MediaCodec.java:1943)
W/MediaCodecRenderer( 4308): at android.media.MediaCodec.configure(MediaCodec.java:1872)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.configure(SynchronousMediaCodecAdapter.java:43)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.configureCodec(MediaCodecVideoRenderer.java:580)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:1143)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1040)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecOrBypass(MediaCodecRenderer.java:604)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1470)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:640)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readToFlagsOnlyBuffer(MediaCodecRenderer.java:994)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:844)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:892)
W/MediaCodecRenderer( 4308): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:467)
W/MediaCodecRenderer( 4308): at android.os.Handler.dispatchMessage(Handler.java:102)
W/MediaCodecRenderer( 4308): at android.os.Looper.loop(Looper.java:164)
W/MediaCodecRenderer( 4308): at android.os.HandlerThread.run(HandlerThread.java:65)
E/ExoPlayerImplInternal( 4308): Playback error
E/ExoPlayerImplInternal( 4308): com.google.android.exoplayer2.ExoPlaybackException: MediaCodecVideoRenderer error, index=0, format=Format(1, null, null, video/avc, null, -1, null, [1920, 1080, 30.0], [-1, -1]), format_supported=YES
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:542)
E/ExoPlayerImplInternal( 4308): at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 4308): at android.os.Looper.loop(Looper.java:164)
E/ExoPlayerImplInternal( 4308): at android.os.HandlerThread.run(HandlerThread.java:65)
E/ExoPlayerImplInternal( 4308): Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.qcom.video.decoder.avc, Format(1, null, null, video/avc, null, -1, null, [1920, 1080, 30.0], [-1, -1])
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1047)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecOrBypass(MediaCodecRenderer.java:604)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1470)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:640)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readToFlagsOnlyBuffer(MediaCodecRenderer.java:994)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:844)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:892)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:467)
E/ExoPlayerImplInternal( 4308): ... 3 more
E/ExoPlayerImplInternal( 4308): Caused by: android.media.MediaCodec$CodecException: Error 0xfffffff4
E/ExoPlayerImplInternal( 4308): at android.media.MediaCodec.native_configure(Native Method)
E/ExoPlayerImplInternal( 4308): at android.media.MediaCodec.configure(MediaCodec.java:1943)
E/ExoPlayerImplInternal( 4308): at android.media.MediaCodec.configure(MediaCodec.java:1872)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.configure(SynchronousMediaCodecAdapter.java:43)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.configureCodec(MediaCodecVideoRenderer.java:580)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:1143)
E/ExoPlayerImplInternal( 4308): at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodecWithFallback(MediaCodecRenderer.java:1040)
E/ExoPlayerImplInternal( 4308): ... 10 more
I/zygote ( 4308): Background concurrent copying GC freed 2963(417KB) AllocSpace objects, 2(56KB) LOS objects, 49% free, 9MB/18MB, paused 920us total 230.639ms
I/zygote ( 4308): Do full code cache collection, code=124KB, data=100KB
I/zygote ( 4308): After code cache collection, code=88KB, data=59KB
I/OpenGLRenderer( 4308): Initialized EGL, version 1.4
D/OpenGLRenderer( 4308): Swap behavior 2
$ flutter doctor -v
[✓] Flutter (Channel stable, 2.0.3, on Linux, locale en_US.UTF-8)
• Flutter version 2.0.3 at /home/juancarlos/snap/flutter/common/flutter
• Framework revision 4d7946a68d (2 weeks ago), 2021-03-18 17:24:33 -0700
• Engine revision 3459eb2436
• Dart version 2.12.2
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at /home/juancarlos/Android/Sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: /home/juancarlos/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
• All Android licenses accepted.
[✓] Android Studio
• Android Studio at /home/juancarlos/android-studio
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
[✓] Connected device (1 available)
• sdk gphone x86 arm (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• No issues found!
⚠️ Please, «thumbs up» this issue to get it prioritized by ExoPlayer team.
Thanks.
Выбирая где посмотреть фильм, можно увидеть много сайтов. Полный сборник фильмов можно найти на сайте КиноПоиск. Там есть много сериалов, фильмов, мультфильмов для всех возрастов и с разным направлением. Поэтому когда кто-то ищет фильм, то смотрят, если ли он на этой площадке. Но иногда возникают ошибки при использования КиноПоиска, поэтому приходится их как-то решать. Иногда она появляется при воспроизведении защищенного видео.
Как устранить ошибку воспроизведения на КиноПоиск?
Есть 3 основные действия, которые нужно сделать.
- Начать нужно с обновления браузера. Это правильный и достаточно простой шаг. Ведь иногда видео не воспроизводится на браузерах со старым обновлением. В этом случае нужно включить автоматическое обновление, после чего ошибка может пропасть.
- Если обновление в порядке, но видео не воспроизводится, нужно перезапустить устройство и браузер. Возможно такое, что обновления уже актуальный и установлены, но ещё не используются, так как устройство не перезапускалось. Иногда при запуске браузера включаются не все плагины. Поэтому перезагрузка помогает запустить все нужные элементы и «заставить» их работать.
- Перенастроить воспроизведение защищенного контента.
Инструкции для разных браузеров
Иногда такое сообщение появляется даже в тех браузерах, которые обновленные до последней версии. В этом случае нужно смотреть настройки. Обычно там автоматически запрещается просмотр защищенного контента. Чтобы отключить данную функцию, нужно сделать несколько последовательных действий. Для каждого браузера свои настройки.
Яндекс браузера
- Нажать на 3 горизонтальных полоски и запустить «настройки»;
- Слева выбрать вкладку «Сайты»;
- Внизу блока будет раздел «Расширение настройки сайтов»;
- В разделе «защищенное содержимое» включить две функции: Разрешить воспроизведение защищенного контента и Разрешить использование идентификаторов устройства.
- Перезагрузить браузер.
Гугл хром
- Нажать в правом верхнем углу на три точки и выбрать «настройки»;
- Выбрать раздел Конфиденциальность и безопасность;
- Запустить «Настройки сайтов»;
- Выбрать «дополнительные настройки контента»;
- Перейти в раздел «защищенный контент»;
- Включить те же опции, что и в Яндекс браузере;
- Перезагрузить браузер.
Мозила Firefox
- Нажать на 3 горизонтальных полоски и запустить Настройки;
- Выбрать раздел «основные»;
- В пункте Содержимое использующее технические средства…, включить «Воспроизводить контролируемое DRM…»;
Опера
- Нажать на «О», зайти в настройки, включить «дополнительно» и запустить вкладку «Безопасность»;
- Выбрать Конфиденциальность и безопасность, зайти в настройки контента и выбрать защищенное содержимое;
- После этого дать доступ воспроизведению защищенного контента и использовать идентификацию;
- Перезапустить браузер.
Актуальное на этой неделе:
11.04.2022
Если вам на карту неожиданно пришли деньги, что делать?
Когда поступают деньги на карту, владелец обычно знает, что и откуда «падает». Родственник прислал, долг…
Далее
06.04.2022
Как добавить VPN на Андроид через настройки
Ограничения доступа в интернет раздражает и не дает использовать интересные подключения. Проблема решается…
Далее
06.04.2022
Как создать канал в Telegram: пошаговое руководство и советы
Собственный Telegram-канал может завести любой человек. Мессенджер в данном случае никого не ограничивает. При…
Далее
19.03.2022
Код ошибки 60-02 и 01-03 в Сбербанк Онлайн – как исправить?
«Сбербанк онлайн» — это удобный сервис, позволяющий проводить финансовые манипуляции из любой точки мира….
Далее
greycat
Senior MemberАвтор темы
555
#
8 октября 2016 12:00
Редактировалось greycat, 66 раз(а).
Существует 2 версии этой приставки:
на 7(9) андроиде (Tanix TX9S на Amlogic S912) и новая на 11 андроиде (Tanix W2 на Amlogic S905W2)
Характеристики:
Память 2/8 Гб
LAN 1Гбит на Tanix TX9S и 100Мбит на Tanix W2
WIFI 2.4GHz/5GHz
Bluetooth 4.1
На Tanix W2 есть AV и s/pdif (оптический)
Обсуждение Tanix W2 с 45-й страницы этой темы.
Для прошивки подходит метод через USB Burning Tool
Так выглядит экран SB-317 и SB-303 после прошивки SLIMBOX
Данная приставка гораздо слабее 317-й, нет wi-fi и блютуз, но тоже можно пользоваться.
Прошивка SLIMBOX для SB-303
В результате получим достаточно шуструю приставку для своих характеристик, но родной пульт перестанет работать.
Рекомендую использовать аэромыши типа G20S-pro
Все что касается предыдущих приставок от МТС, подробно разобрали на 4pda и в этой теме до 12 страницы
1. CoreElec: ссылка 1, ссылка 2, 4pda
2. Отличия Android TV от google TV, чистого андроида и fire os на смарт тв боксах
3. Как прошить ТВ бокс на Аmlogic процессоре
4. решение проблемы с вылетом в рекавери
ссылка
Все эксперименты с прошивками на Ваш страх и риск. После прошивки лишаетесь гарантии МТС в любом случае, т.к. прошивку от МТС восстановить не получится, ее просто нету ни у кого
Сергей Потапов
Noby
Member
102
#
14 октября 2021 20:32
Вопрос…
Как у 303 с 4к дела (внешний винт/сеть/ТВ)?
Добавлено спустя 1 минута 28 секунд
По редбоксу тот же вопрос
greycat
Senior MemberАвтор темы
555
#
15 октября 2021 19:16
если есть 4к телик, то такими приставками лучше не пользоваться.
либо вообще без приставки, либо купить что то получше.
50р за 317 приставку не так уж и много, хотя тоже для 4к не фонтан. там вроде 60 кадров не идет.
Сергей Потапов
acrid71
Senior Member
784
#
16 октября 2021 19:35
greycat:
50р за 317 приставку не так уж и много
А где так продают?
Noby
Member
102
#
16 октября 2021 20:44
Редактировалось Noby, 1 раз.
greycat:
если есть 4к телик, то такими приставками лучше не пользоваться.
либо вообще без приставки, либо купить что то получше.
50р за 317 приставку не так уж и много, хотя тоже для 4к не фонтан. там вроде 60 кадров не идет.
вопрос в дркгом
greycat
Senior MemberАвтор темы
555
#
16 октября 2021 21:35
acrid71:
А где так продают?
на прошлой странице спросите у того, кто так купил
видимо есть те, кто сливает халявные приставки от мтс на барахолке.
Noby:
вопрос в дркгом
у 303 вроде как возможен такой режим, но будут пропуски кадров в ютуб, под рукой ее уже нет и перепрошита она. там наоборот интерфейс перевели в 720р, чтобы ожила и не была настолько тупой, так что про 4к на них стит забыть.
Сергей Потапов
Noby
Member
102
#
17 октября 2021 08:41
спасибо
acrid71
Senior Member
784
#
17 октября 2021 08:46
greycat:
там наоборот интерфейс перевели в 720р, чтобы ожила и не была настолько тупой, так что про 4к
А разве перевод фейса в нижнее разрешение повышает TTХ?
greycat
Senior MemberАвтор темы
555
#
17 октября 2021 11:27
ну видимо да, я просто говорю о факте, не зря же так сделали в прошивке слимбокса для 303.
для АТВ видимо не хватает оперативки.
вообще приставки с 1гб оперативки — это шлак.
минимум 2гб.
Сергей Потапов
3034663
Neophyte Poster
1
#
5 ноября 2021 20:33
Что делать если на mts box 31 выдает следующее: Не удалось проинициализировать OMX.amlogic.avc.decoder.awesome
Как эту проблему исправить? Это высвечивается когда в КиноПоиске фильм пытаюсь посмотреть. Помогите пожалуйста
wolkow
Member
302
#
7 ноября 2021 15:15
Редактировалось wolkow, 1 раз.
Добрый день! Столкнулся с такой проблемой:
Приставка с прошивкой от MTC после перезагрузки загрузилась в Recovery Mode. Сбросы не помогли. Решил прошить sbx_tanix_tx9s_atv_v11_2_new ( из шапки).
Прошивал все согласно инструкции через USB_Burning_Tool. Но приставка грузилась в Recovery Mode и появлялись ошибки.
Failed to moant /cache (Invalid argument)
Failed to moant /cache/ recovery/last_locale
Failed to moant /cache (Invalid argument)
Не знаю что повлияло, но отключив кабель Ethernet, приставка запустилась. После перезагрузки опять Recovery Mode. и так постоянно. То включается, то Recovery Mode.
Хотел бы уже сделать сброс на заводские настройки и кэш, но в Recovery Mode не срабатывает пульт, не перемещается курсор.
Программы для чистки, почему то не устанавливаются. Приставка вроде блокирует.
Может кто подскажет в какую сторону копать? Может через ПК как то сделать сбросы?
Спасибо
greycat
Senior MemberАвтор темы
555
#
7 ноября 2021 23:28
wolkow:
Хотел бы уже сделать сброс на заводские настройки и кэш, но в Recovery Mode не срабатывает пульт, не перемещается курсор.
а если мышку подключить или пульт-аэромышь?
к «заводстким», т.е. на прошивку МТС уже не получится обнулить все равно, по гарантии ее тоже не примут.
Сергей Потапов
siongroup
Senior Member
556
#
8 ноября 2021 19:31
Tot
wolkow:
Добрый день! Столкнулся с такой проблемой:
Приставка с прошивкой от MTC после перезагрузки загрузилась в Recovery Mode. Сбросы не помогли. Решил прошить sbx_tanix_tx9s_atv_v11_2_new ( из шапки).
Прошивал все согласно инструкции через USB_Burning_Tool. Но приставка грузилась в Recovery Mode и появлялись ошибки.
Failed to moant /cache (Invalid argument)
Failed to moant /cache/ recovery/last_locale
Failed to moant /cache (Invalid argument)
Не знаю что повлияло, но отключив кабель Ethernet, приставка запустилась. После перезагрузки опять Recovery Mode. и так постоянно. То включается, то Recovery Mode.
Хотел бы уже сделать сброс на заводские настройки и кэш, но в Recovery Mode не срабатывает пульт, не перемещается курсор.
Программы для чистки, почему то не устанавливаются. Приставка вроде блокирует.
Может кто подскажет в какую сторону копать? Может через ПК как то сделать сбросы?
Спасибо
Еще раз нормально прошить через Usb Burning tool — может какой другой прошивкой например от BlackVictor. Затем пробовать включать. Судя по ошибке у вас не монтируются разделы значит проблема во внутренней памяти eMMC. На крайняк можно прошить внутреннюю память через замыкание на плате — так точно она прошьется как положено.Также обратите внимание на питание — блок питаняи там корявый и не всегда нормально держит 5в.
По гарантии элементарно сдать можно — просто во время прошивки через Usb Burning Tool когда идет запись основного раздела data выдерните кабель которым прошивали и затем можете идти в МТС. Приставка грузится не будет, а в МТС сервисе разбираться какие разделы в тв боксе запорчены точно не будут. Они ее заново зашьют на ихнюю прошивку.
Выживает ведь не тот кто умеет жить на пять, а тот кто просто не умеет умирать!
Felixx
Senior Member
508
#
10 ноября 2021 07:51
Редактировалось Felixx, 2 раз(а).
Здравствуйте всем. Знает может кто, что за ошибка и как исправить? 06.11.2021 купил на МТС, вчера дошли руки ее подключить к МТС ТВ, вроде все должно быть просто (подключал по кабелю, не wifi) но пошло совсем не так. После авторизации, потребовал какой-то код. Перепробовал се, но ничего не подошло. Звонил в техподдержку, сказали это типа для взрослых контект, но я заходил в основной профиль и там не должно быть ни какого доп. кода. А он у меня был. Собственник жена, поэтому сказали звонить ей (оператор был парень). Потом звонили еще раз, сказали выйти из профиля и зайти заново, никак не помогло. В третий раз, сказали что услуга не подключена вообще и надо ее подключить и потом все заработает. В итоге то же самое. После снова вышел из профиля, выключил и после включения, появилась такая ошибка. Что это за ошибка и лечится ли? Примут ли по гарантии ее? и что за пин код был такой?
ПРИСТАВКА Android TV Box SB-317
A dream becomes a goal when action is taken toward its achievement
Felixx
Senior Member
508
#
11 ноября 2021 09:53
Редактировалось Felixx, 1 раз.
Felixx:
Здравствуйте всем. Знает может кто, что за ошибка и как исправить? 06.11.2021 купил на МТС, вчера дошли руки ее подключить к МТС ТВ, вроде все должно быть просто (подключал по кабелю, не wifi) но пошло совсем не так. После авторизации, потребовал какой-то код. Перепробовал се, но ничего не подошло. Звонил в техподдержку, сказали это типа для взрослых контект, но я заходил в основной профиль и там не должно быть ни какого доп. кода. А он у меня был. Собственник жена, поэтому сказали звонить ей (оператор был парень). Потом звонили еще раз, сказали выйти из профиля и зайти заново, никак не помогло. В третий раз, сказали что услуга не подключена вообще и надо ее подключить и потом все заработает. В итоге то же самое. После снова вышел из профиля, выключил и после включения, появилась такая ошибка. Что это за ошибка и лечится ли? Примут ли по гарантии ее? и что за пин код был такой?
ПРИСТАВКА Android TV Box SB-317
Приставку просто перезагрузил и все заработало. Пин код был вшит в систему, в заводскую настройку. Решение: В личном кабинете, устанавливаешь код доступа к профилю, и все заработало. Если этого не сделать, то зайти в профиль нельзя, т.к. не задан пароль.
A dream becomes a goal when action is taken toward its achievement
katete
Member
236
#
14 ноября 2021 19:13
Редактировалось katete, 1 раз.
Dlell
The_Maximus
Neophyte Poster
26
#
21 ноября 2021 17:23
Прошил SB-317 по инструкции из шапки. Шил проводом юсб-с в ноут, юсб обычный — в приставку. Порт — тот, что ближе к зарядке. Иначе не работало. Сначала юсб провод, потом зажимаем резет кнопку зубочисткой, потом шнур питания и через секунду зубочистку вынимаем. Когда шил, появилась красная надпись и процесс встал. Попробовал заново, сначала не получалось (провода и так и эдак тыркал), потом ноут тихо проиграл звук о подключении и процесс сам возобновился. Итог — пару минут заливки прошивки (вдохнул, когда остановилось на 88% и подвисло на минуту), и первое включение шло минут три наверное. Пульт работал сразу. Установил Zack remote на телефон и на приставку (режим аэромыши включается за 35 центов, но и без него работает), установил Кинопоиск и офигел от картинки, которую мне выдал мой старый горизонт. На мтс прошивке кинопоиск ставился, но не работал. Сейчас сижу и думаю за что я платил мтс, млин, не используя приставку во всю мощь и где я был раньше. Для владельцев х7, где полагается 3 приставки за 5 руб — вообще можно не парится. Даже, если окирпичится одна, можно взять ещё одну. Ах, да. В настройках пришлось высоту и ширину экрана уменьшить до 95%, чтобы приложение от мтс тв вписался в экран. Оно, кстати, из гугла вполне себе скачалось и встало без проблем.
Может кому мой пост поможет сэкономить пару нервов, когда будет казаться, что не получается)) сори за многабукав..
MaxfromBY
FreemanD
Member
171
#
3 декабря 2021 11:18
Народ,нужна помощь.SB-317 не устонавливается приложение google,соответственно отсутствуеттголосовой поиск в приложениях.Кто сталкивался с подобным,помогите.
satpazan
Member
239
#
3 декабря 2021 11:43
FreemanD:
Народ,нужна помощь.SB-317 не устонавливается приложение google,соответственно отсутствуеттголосовой поиск в приложениях.Кто сталкивался с подобным,помогите.
Так прошейте на слимбокс…
FreemanD
Member
171
#
3 декабря 2021 12:01
satpazan:
FreemanD:
Народ,нужна помощь.SB-317 не устонавливается приложение google,соответственно отсутствуеттголосовой поиск в приложениях.Кто сталкивался с подобным,помогите.
Так прошейте на слимбокс…
При нажатии на кнопку ресет ,что нибудь должно с приставкой происходить?Я когда нажимаю на её ничего не происходит.Соответственно программа для прошивкиине видит приставку или же у меня кабель фиговый
FreemanD
Member
171
#
3 декабря 2021 20:49
Нашёл способ и приставка определяется программой для прошивки,но после 1%загрузки появляется ошибка красным цветом ,что то про бутлодер написано,кто знает что можеттбыть?
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Closed
AntonAFA opened this issue
Feb 12, 2018
· 58 comments
Closed
MediaCodec initialisation fails.
#3835
AntonAFA opened this issue
Feb 12, 2018
· 58 comments
Assignees
Comments
Issue description
On certain devices that use OMX.MTK.VIDEO.DECODER.AVC decoder, on DRM content ONLY we receive the below error.
Reproduction steps
- Initialise SimpleExoPlayer
- Prepare MediaSource with drm.
- Note, that in prepare step, we are NOT attaching SimpleExoplayerView to view hierarchy, and
only doing so, after player state READY received. - Get the crash, immediately after prepare() called.
Link to test content
«uri»: «https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd»
«drm_license_url»: «https://proxy.uat.widevine.com/proxy?provider=widevine_test»
Version of ExoPlayer being used
We can see this issue reproduced on Exoplayer 2.5.0 and above (including 2.6.1)
Previous Exoplayer versions work as expected.
Device(s) and version(s) of Android being used
Device — Meizu M5C, Lenovo K4 and Moto C+ (all of them with OMX.MTK.VIDEO.DECODER.AVC)
Android version — 6.0
### A full bug report captured from the device
com.google.android.exoplayer2.ExoPlaybackException
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.throwDecoderInitError(MediaCodecRenderer.java:418)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:405)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.MTK.VIDEO.DECODER.AVC, Format(1, null, video/avc, 720
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:405)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: android.media.MediaCodec$CodecException: start failed
at android.media.MediaCodec.native_start(Native Method)
at android.media.MediaCodec.start(MediaCodec.java:1898)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:397)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Was able to reproduce your problem on a Moto C+. It seems the device has problems switching output surfaces and needs a workaround. This is similar to issues with other devices we had in the past (e.g. #3355, #3439).
Can you provide us with the Build.DEVICE names of Meizu M5C and Lenovo K4 to add them to our workaround?
As i see you already support something related to OMX.MTK codec in your workaround. Or you talking about some other workaround?
Will provide you with device info tomorrow.
Yes, the existing workaround checks decoder name and device name to be as restrictive as possible (see here). That’s why I need the device names of the devices where it doesn’t work to add to this list.
Here is the device names(same as appear in your Util.DEVICE)
Meizu M5C — M5c
Lenovo K4 Note — A7010a48
Anyway, I tried to change the codecNeedsSetOutputSurfaceWorkaround(String name), so that Meizu M5c will be included in the list of workaround needed devices. The result was the same as in reported bug. Even if I force codecNeedsSetOutputSurfaceWorkaround always return true, it is still crashing. Do you manage to reslove issue on Moto C++ by adding it to the workaround list?
Is there something more that I need to do in order to apply this workaround on Meizu?
Yes, I added "panell_s".equals(Util.DEVICE)
to the workaround list and this solved the issue for the Moto C+.
Were you able to test if it works for the Lenovo K4?
First of all, that is good news, because one of the devices our customer reported on, was Moto C+. So I will check it with them.
I am testing it on Meizu. Unfortunately I have no Lenovo K4 around me. As I mentioned above, even i force hardcoded codecNeedsSetOutputSurfaceWorkaround always return true and compile on Meizu it does not have any effect. Is there anything that I probably missing?
Not if it’s exactly the same issue.
Unfortunately, I don’t have access to neither Meizu M5c nor Lenovo K4, so it’s difficult to check what may cause it. Are the reproduction steps and the error message above the same for all three devices? Or is there something else?
Yes, the flow is the same.
For the matter of fact, I even dont see that exoplayer enter this code block.
getCodecInfo always return null, so dummySurface never initialised.
private void setSurface(Surface surface) throws ExoPlaybackException {
if (surface == null) {
// Use a dummy surface if possible.
if (dummySurface != null) {
surface = dummySurface;
} else {
MediaCodecInfo codecInfo = getCodecInfo(); // getCodecInfo always return null, so dummySurface never initialised.
if (codecInfo != null && shouldUseDummySurface(codecInfo.secure)) {
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
surface = dummySurface;
}
}
}
}
maybeInitCodec() always happened only after setSurface(Surface surface) was called two times
and the incoming Surface is always null.
Actually, onCodecInitialized(String name, long initializedTimestampMs,
long initializationDurationMs) does not happen also.
Can you provide more details on why setSurface is called two times? It’s usually only called once when you attach the UI.
setSurface was called twice because we used old exoplayer api where you was supposed to call player.setSurfaceView(null) before you apply new surface (in order to clean the previous one. Now you are doing it with player.clearVideoSurfaceView() so the surface can be removed by SurfaceHolder) I updated our api to be aligned with yours. Now setSurface() called only once. But the issue still there.
Another thing that I see is that setOutputSurfaceV23(codec, surface);
never happened.
surface is null, so if (this.surface != surface)
will never enter the block where you actually apply the workaround.
From what I see the first time DummySurface created is in configureCodec(MediaCodecInfo codecInfo, MediaCodec codec, Format format, MediaCrypto crypto){ }
with if (dummySurface == null) { dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure); }
But I think it is too late, because almost immediately called codec.start();
that actually crash the player
With the workaround in place, dummySurface
should never be created. The creation in configureCodec
is guarded by a call to shouldInitCodec
which also checks whether this workaround is needed.
When exactly do you attach the UI? I added a listener to onPlayerStateChanged
and when the playback state changes to Player.STATE_READY
for the first time, the UI is attached. When doing this, the codec.start
method is called as a result of setSurface
and not because onInputFormatChanged
as in your case. There seems to be a difference in the way I try to reproduce the problem.
So in order to be maximum aligned with you I have moved to work on your demo application.
I want to be sure that we dont miss anything.
I did some small changes in player_activity.xml and PlayerActivity.java in order to reproduce issue on my device.
Changes I made: player_activity.xml —> I comment out this block
<com.google.android.exoplayer2.ui.SimpleExoPlayerView android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
and added this view instead:
<FrameLayout android:id="@+id/test_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
This should simulate my parent view to which I attach player view.
In PlayerActivity In onCreate()
-
I get the reference to the test_view,
testRootView = findViewById(R.id.test_view);
-
create SimpleExoplayerView programmatically
simpleExoPlayerView = new SimpleExoPlayerView(this);
-
subscribe to STATE_READY and when it received add simpleExoPlayerView to testRootView
if(playbackState == Player.STATE_READY) {
testRootView.addView(simpleExoPlayerView);
}
Also I added Meizu device name in MediaCodecVideoRenederer. Workaround method now looks like that:
private static boolean codecNeedsSetOutputSurfaceWorkaround(String name) {
// Work around https://github.com/google/ExoPlayer/issues/3236,
// https://github.com/google/ExoPlayer/issues/3355 and
// https://github.com/google/ExoPlayer/issues/3439.
return (("deb".equals(Util.DEVICE) || "flo".equals(Util.DEVICE))
&& "OMX.qcom.video.decoder.avc".equals(name))
|| (("tcl_eu".equals(Util.DEVICE) || "SVP-DTV15".equals(Util.DEVICE)
|| "BRAVIA_ATV2".equals(Util.DEVICE))
&& "OMX.MTK.VIDEO.DECODER.AVC".equals(name)
|| "M5c".equals(Util.DEVICE) && "OMX.MTK.VIDEO.DECODER.AVC".equals(name));
}
From what I see from debugging the code flow looks like that:
setSurface(Surface surface)
called with surface null, so we exit this function without doing anything.- We get in
onInputFormatChanged(Format newFormat)
with audio codec first. so we continue tomaybeInitCodec()
and exiting this function ok. - We get
onInputFormatChanged(Format newFormat)
once again. This time with video codec. And going intomaybeInitCodec()
shouldInitCodec()
returns true.surface != null
is false butshouldUseDummySurface(codecInfo.secure);
is true. So the statement is true.shouldUseDummySurface()
returns true. Here all the statements return true exceptDummySurface.isSecureSupported(context)
that returns false. but because of || sign it is enough that!codecIsSecure
return true for this statement to be also true.- So then we going into
configureCodec()
(all the workaround flags inmaybeInitCodec()
are set to false). inconfigureCodec()
the surface is null. Assertion not throwing exception. dummySurface instantiated.
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
- And from there we continue to
codec.start();
and Boom! exception thrown.
You say that dummySurface should never be created in a proper workaround mode. But in my case it happens to work in exact that way. Also the codec.start
is called not from setSurface
. Any idea for reason why it can happen? Note, that I in purpose reproduce this issue in your demo app with your drm content in order to be maximum aligned to your workspace. exoplayer branch is release-v2
It will be grate, if you add Meizu and Lenovo K4 devices to the list of excluded devices and push it on some side branch, that I can check if this fix apply for them. I am quite sure, that there is something that I am missing.
Here is the device names(same as appear in your Util.DEVICE)
Meizu M5C — M5c
Lenovo K4 Note — A7010a48
Thanks a lot for this detailed analysis! Not many people make this effort to help us debug a problem
It turns out that there is a difference I didn’t know about (thanks to @ojw28 for pointing this out). The original fix for other devices (#3439) included some further changes to prevent the DummySurface from being instantiated. Please have a look at this commit to see the details. I guess it will work when you add this change to your code (especially that shoulduseDummySurface
also checks for the workaround).
I’ll add the Meizu M5C and the Lenovo K4 to our list.
Thanks for your solution. I made the changes you suggest and it seems to work both on Meizu M5c and Lenovo K4 Note.
For some reason it did not work on Moto C+ that we tested on. When I print it Util.DEVICE
, I could see that the name is slightly differ from the one you provide.
You told that it is «panell_s» , but in my case the name was «panell_p». Probably there is some minor difference in devices, and therefore they have different names. Anyway, adding «panell_p» to the device list solved the issue.
What I am wondering now, is how many devices out there that we does not know about them having this problem. Is there more general solution in plan, then just excluding device-device? Also, I observed that all of the our problematic devices have same chipset and codec (just to take it in your consideration). Maybe there we can detect some patterns and exclude devices by them and not by name.
Another thing I want to ask you about, is your release plans. I am not asking for exact date, just want to know if for now I should think about some temporary solution, or just wait for your release.
Thank you very much for your support.
Yes, there is also panell_d, panell_dl and panell_dp. Guess I better change it to include all devices starting with «panell» then.
We also discussed the same question — whether we should enable the workaround for certain API levels and decoders for all devices or something similar. Because we also don’t know for sure how many devices out there have this problem. Using the chipset may be a good idea, need to think about this a little bit further.
For our release plans, there is probably a new release in the next couple of days.
Thanks again.
I was thinking about possible solutions, and came to a little bit different possible approach. If you provide some sort of Settings API that can give application (me) ability to decide if I want this workaround or not for example: player.useDummySurfaceWorkaround(true)
, I can catch this specific exception once and enable workaround for all previous sessions for this device. This will release you from responsibility of tracking all the problematic devices and adding them to the endless workaround list. On my side I can also relax and forget about this bug
The only thing I am worried about is this exception unique for this sort of behaviour, or it can be thrown in some other circumstances?
This problem often results in the application not responding on these devices instead of an exception. Especially when switching between two real surfaces. That means we can’t just always try first and enable the workaround as soon as it fails.
If you want to catch the exception and then set a flag in your app, you can still do so by overriding shouldInitCodec
in MediaCodecVideoRenderer
to disable initializing the dummy surface if surface == null
. This extended renderer can then be used in ExoPlayer by overriding the buildVideoRenderers
in DefaultRenderersFactory
to return your renderer. And then pass in this renderers factory to ExoPlayerFactory.newSimpleInstance
.
ojw28
pushed a commit
that referenced
this issue
Feb 16, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 16, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 20, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 20, 2018
Hi @tonihei and @ojw28, thank you for fixing this issue.
I want to express my concerns about the «device-specific workaround» approach.
What we did (I work with @AntonAFA) is the following:
- A customer has reported this issue on Moto C+ and Lenovo K4 Note
- We wanted to reproduce the issue locally, so we looked online for devices we can buy that have the same chipset as those devices (MT6737 and MT6753, respectively). The reported devices don’t sell here, and it was sort-of a shot in the dark.
- We found that Meizu M5c has the same chipset as the Moto C+, so we bought it and easily reproduced the issue.
But there are many other phones with the same chipset — we just chose one that was easy to get. So either it was just a lucky guess, or all those other phones (which are not explicitly named by ExoPlayer) will also fail.
In addition — as mentioned above, the Lenovo K4 Note has a different MediaTek chipset (albeit in the same family, MT67xx), and it fails in the same way.
Just my 2 cents.
We agree that the current approach isn’t doing a good job of targeting all affected devices. Although on the plus side, it’s likely that we’re targeting the popular ones; there are probably quite a lot of devices that barely anyone is using.
An approach that targets the chipset would be preferable, but I’m not sure how to do that. I don’t think there’s anything suitable in Build. Do you have any idea how we’d be able to target the workaround to a specific chipset?
Hi @ojw28,
From what I found, the best (read: least bad) source of the chipset id is android.os.SystemProperties.get("ro.board.platform")
(a private API, which is why it’s bad). For the Meizu M5c it gives me mt6737m
.
I don’t know why the extra «m»; probably a variant.
I’d read it into a static final field and query when required (maybe even create a «workaround-map»).
At the end of the day, it’s a matter of choosing between two hacks, so pick your poison. Using the chipset is more robust IMHO because I’m pretty sure that all devices with the same chipset have the same MediaCodec issues (also think about the adaptation workaround (#3257), which is required on some Exynos devices but not on MediaTek).
Being a Googler, can you reach out to the Android people and ask them to add the chipset id to android.os.Build
? Moreover, maybe Google should maintain a public device properties/capabilities db.
As for device popularity — we have a large customer in India; even unpopular, cheap, devices can have a few tens of thousands of users.
Hello team. As was previously discussed on this thread, we made some sort of workaround test, that checks and gather potentially codec problematic devices. Those in order to report you and make exoplayer better.
The workaround is pretty straight forward (as referenced here by @noamtamim https://github.com/kaltura/playkit-android/blob/2e58d94c0c9e2b962e9f31699f1f1c2b07d80790/playkit/src/main/java/com/kaltura/playkit/player/MediaCodecWorkaroundTest.java).
Before actually playing real content we first instatiate «test» player with local asset and dummy drm license. We listen for the Player events which should indicate us, if media with drm was managed to play on the device. Receiving of
MediaCodecRenderer.DecoderInitializationException
will indicate us that combination of the device specification and codec might be problematic. So we gather this device info and raise some flag that will make your codecNeedsSetOutputSurfaceWorkaround()
return true.
The problem we face now, is that amount of «problematic» devices that was collected by this test is huge. So I believe, that our test covers to much use-cases and probably we should somehow narrow/filter MediaCodecRenderer.DecoderInitializationException
by its cause. Can you help us with this filter by explaining which reasons for MediaCodecRenderer.DecoderInitializationException
might be relevant for us?
As I see there are only 3 reasons where this exception might be thrown
- When
DecoderQueryException
is thrown - When codecInfo is null in
maybeInitCodec
block - And when trying to configure codec in the same block by calling
configureCodec(codecInfo, codec, format, wrappedMediaCrypto);
Will appriciate your response on the subject
I tried using your test code and the assets (mp4+mp4+init data) and also get workaroundRequired = true
for a device which should not need the workaround.
Could it be that all devices are labelled as needing the workaround with this approach? Or am I missing something?
No, we label device as needed workaround only when we get MediaCodecRenderer.DecoderInitializationException
. Probably there might be additional reasons for getting thes exception. And thats what I am trying to figure out. On which device did you run the test?
I used a Nexus 6P and got a DecoderInitializationException as well. I fear that the workaround test doesn’t cover the real thing because it does never switches (or sets) surfaces and probably fails for other reasons.
What was the cause fot this DecoderInitializationException
? Can you suggest some more convinient way of doing that test? Maybe, ad some «setSurface» block?
After looking into this in more detail, I think setting the surface shouldn’t be necessary because the DummySurface is still created (as you don’t set a surface at all). It just wouldn’t catch devices which only have problems with switching surfaces but that’s probably fine for the first try.
However, it seems the test content is too small. The reason is fails for me is «Unsupported WxH = (32)x(32) supported range is min(64)x(64) — max(4096)x(4096)». When you look at the failing stack traces, you’ll notice that it fails in MediaCodec.configure
and not in MediaCodec.start
as in the stack trace above in your first post.
@tonihei the problem is that at the time the test runs, we don’t have a license URL that will respond correctly. Are you saying that when you set this proxy URL the response it provides (which is obviously not a valid license response) is good enough? What if I’ll be offline at the time of testing?
More importantly, the idea for the fakeDrmCallback with a delay of 10 seconds is making sure the license will not fail before the test reaches a conclusion.
In other words — the test works for you on a device that really shouldn’t be problematic (shouldn’t be listed in the workaround list). But I suspect it will also skip the real culprits (such as Meizu 5c).
The fakeDrmCallback
doesn’t work because the player just waits for 10 seconds and then issues an IllegalArgumentException because the key response is null.
To get a valid Widevine license (which allows to setup the secure surface), you either need the online license request or you manage to obtain an offline license which never expires.
Alternatively, [thanks to @AquilesCanta for pointing this out], you can use ClearKey to provide the key directly in the media. This should allow you to run the test offline.
Unfortunately, I don’t have one of the failing devices available at the moment. So I can’t confirm whether the test with the real drm callback actually fails.
Final remark: You should probably also release the test player for all other errors which are not a DecoderInitializationException to prevent resource leaking.
- I considered a license that never expires (I can create such a thing in our DRM server), but this license is still bound to the device that created the request — so it’s not something I can hold as an asset
- ClearKey would be nice, but I’m pretty sure it’s only supported from Android 7.1 and up. We need to support 4.3.
- I don’t need the license request to succeed, because I don’t really intend to play the file. That’s the point of the fakeDrmCallback: I want to give the renderer a chance to fail because of the DummySurface issue before it fails for an invalid response.
I want to give the renderer a chance to fail because of the DummySurface issue before it fails for an invalid response.
The problem is that the player never reaches the READY state in such a setup. Instead, after 10 seconds waiting, it gets the wrong key request answers and fails with a DrmSessionException. If I understand you correctly, that’s what you wanted. Waiting for the READY state is then probably not the right way to «pass» the test.
When you say the number of problematic devices is huge — how do you determine that a device is problematic? Do you count the number of positive and negative examples of this workaround test? If so, you should be able to filter by flaky decoder initialization problems for other reasons. This problem should be reproducible 100% of the time, so there shouldn’t be a single passing device of the problematic ones.
Hi @tonihei,
We don’t ever expect the player to be READY. However, we do expect that if it failed with DecoderInitializationException
, it will be because of the DummySurface
issue:
if (error.getCause() instanceof MediaCodecRenderer.DecoderInitializationException) { workaroundRequired = true; }
Putting it all together, I suspect that the only reason for the huge amount of false positives is the video size. Am I right?
BTW, in the released version we did move the player.release()
call outside of the if
.
Yes, that seems fine. I think I got quite confused that your example code set workaroundRequired = false
when READY was reached which clearly wouldn’t work.
And yes I agree, that to some extent the failures were due to the video size. Please note that there will be other DecoderInitialization failures for various reasons and you’ll still need to check that the test fails for all devices of the same model.
Thanks for reporting! That really is a never-ending-story ;(
Do you have the Build.MODEL for that? It might be «CAG-L02» or «CAG-L22».
The Build.MODEL is listed as «gobo», but I don’t think it’s a real value. The tested device was not yet released at the time (TAGS=dev-keys), so all the values look strange:
"BRAND": "google",
"MODEL": "gobo",
"MANUFACTURER": "alps",
"TAGS": "dev-keys",
"FINGERPRINT": "google/gobo/gobo:8.1.0/OMB1.171031.003/4428322:user/dev-keys",
The device was released since, but I don’t have anyone that can check on a production device.
The chipset is MT6737M — the same as some other devices listed above.
@tonihei / others — does Google have a database of all the certified Android devices, that contain everything from android.os.Build?
Thanks @tonihei, I didn’t know about this list. Regarding the device, they both use the same chipset, and the issue is there.
Do you also have the culprit decoder name? Forgot to ask about it.
No, sorry. I don’t have the device itself with me.
Let’s dupe this onto #4468, which is newer, but provides a more comprehensive list of (possibly) affected devices. We can use that for tracking.
I think we’ll also go ahead and make codecNeedsSetOutputSurfaceWorkaround
and codecNeedsDummySurfaceSurfaceWorkaround
protected and non-static, as was suggested here.
google
locked and limited conversation to collaborators
Nov 23, 2018
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Closed
AntonAFA opened this issue
Feb 12, 2018
· 58 comments
Closed
MediaCodec initialisation fails.
#3835
AntonAFA opened this issue
Feb 12, 2018
· 58 comments
Assignees
Comments
Issue description
On certain devices that use OMX.MTK.VIDEO.DECODER.AVC decoder, on DRM content ONLY we receive the below error.
Reproduction steps
- Initialise SimpleExoPlayer
- Prepare MediaSource with drm.
- Note, that in prepare step, we are NOT attaching SimpleExoplayerView to view hierarchy, and
only doing so, after player state READY received. - Get the crash, immediately after prepare() called.
Link to test content
«uri»: «https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd»
«drm_license_url»: «https://proxy.uat.widevine.com/proxy?provider=widevine_test»
Version of ExoPlayer being used
We can see this issue reproduced on Exoplayer 2.5.0 and above (including 2.6.1)
Previous Exoplayer versions work as expected.
Device(s) and version(s) of Android being used
Device — Meizu M5C, Lenovo K4 and Moto C+ (all of them with OMX.MTK.VIDEO.DECODER.AVC)
Android version — 6.0
### A full bug report captured from the device
com.google.android.exoplayer2.ExoPlaybackException
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.throwDecoderInitError(MediaCodecRenderer.java:418)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:405)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.MTK.VIDEO.DECODER.AVC, Format(1, null, video/avc, 720
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:405)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: android.media.MediaCodec$CodecException: start failed
at android.media.MediaCodec.native_start(Native Method)
at android.media.MediaCodec.start(MediaCodec.java:1898)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:397)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:839)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:455)
at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:536)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:560)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:306)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:207)
at android.os.HandlerThread.run(HandlerThread.java:61)
Was able to reproduce your problem on a Moto C+. It seems the device has problems switching output surfaces and needs a workaround. This is similar to issues with other devices we had in the past (e.g. #3355, #3439).
Can you provide us with the Build.DEVICE names of Meizu M5C and Lenovo K4 to add them to our workaround?
As i see you already support something related to OMX.MTK codec in your workaround. Or you talking about some other workaround?
Will provide you with device info tomorrow.
Yes, the existing workaround checks decoder name and device name to be as restrictive as possible (see here). That’s why I need the device names of the devices where it doesn’t work to add to this list.
Here is the device names(same as appear in your Util.DEVICE)
Meizu M5C — M5c
Lenovo K4 Note — A7010a48
Anyway, I tried to change the codecNeedsSetOutputSurfaceWorkaround(String name), so that Meizu M5c will be included in the list of workaround needed devices. The result was the same as in reported bug. Even if I force codecNeedsSetOutputSurfaceWorkaround always return true, it is still crashing. Do you manage to reslove issue on Moto C++ by adding it to the workaround list?
Is there something more that I need to do in order to apply this workaround on Meizu?
Yes, I added "panell_s".equals(Util.DEVICE)
to the workaround list and this solved the issue for the Moto C+.
Were you able to test if it works for the Lenovo K4?
First of all, that is good news, because one of the devices our customer reported on, was Moto C+. So I will check it with them.
I am testing it on Meizu. Unfortunately I have no Lenovo K4 around me. As I mentioned above, even i force hardcoded codecNeedsSetOutputSurfaceWorkaround always return true and compile on Meizu it does not have any effect. Is there anything that I probably missing?
Not if it’s exactly the same issue.
Unfortunately, I don’t have access to neither Meizu M5c nor Lenovo K4, so it’s difficult to check what may cause it. Are the reproduction steps and the error message above the same for all three devices? Or is there something else?
Yes, the flow is the same.
For the matter of fact, I even dont see that exoplayer enter this code block.
getCodecInfo always return null, so dummySurface never initialised.
private void setSurface(Surface surface) throws ExoPlaybackException {
if (surface == null) {
// Use a dummy surface if possible.
if (dummySurface != null) {
surface = dummySurface;
} else {
MediaCodecInfo codecInfo = getCodecInfo(); // getCodecInfo always return null, so dummySurface never initialised.
if (codecInfo != null && shouldUseDummySurface(codecInfo.secure)) {
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
surface = dummySurface;
}
}
}
}
maybeInitCodec() always happened only after setSurface(Surface surface) was called two times
and the incoming Surface is always null.
Actually, onCodecInitialized(String name, long initializedTimestampMs,
long initializationDurationMs) does not happen also.
Can you provide more details on why setSurface is called two times? It’s usually only called once when you attach the UI.
setSurface was called twice because we used old exoplayer api where you was supposed to call player.setSurfaceView(null) before you apply new surface (in order to clean the previous one. Now you are doing it with player.clearVideoSurfaceView() so the surface can be removed by SurfaceHolder) I updated our api to be aligned with yours. Now setSurface() called only once. But the issue still there.
Another thing that I see is that setOutputSurfaceV23(codec, surface);
never happened.
surface is null, so if (this.surface != surface)
will never enter the block where you actually apply the workaround.
From what I see the first time DummySurface created is in configureCodec(MediaCodecInfo codecInfo, MediaCodec codec, Format format, MediaCrypto crypto){ }
with if (dummySurface == null) { dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure); }
But I think it is too late, because almost immediately called codec.start();
that actually crash the player
With the workaround in place, dummySurface
should never be created. The creation in configureCodec
is guarded by a call to shouldInitCodec
which also checks whether this workaround is needed.
When exactly do you attach the UI? I added a listener to onPlayerStateChanged
and when the playback state changes to Player.STATE_READY
for the first time, the UI is attached. When doing this, the codec.start
method is called as a result of setSurface
and not because onInputFormatChanged
as in your case. There seems to be a difference in the way I try to reproduce the problem.
So in order to be maximum aligned with you I have moved to work on your demo application.
I want to be sure that we dont miss anything.
I did some small changes in player_activity.xml and PlayerActivity.java in order to reproduce issue on my device.
Changes I made: player_activity.xml —> I comment out this block
<com.google.android.exoplayer2.ui.SimpleExoPlayerView android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
and added this view instead:
<FrameLayout android:id="@+id/test_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
This should simulate my parent view to which I attach player view.
In PlayerActivity In onCreate()
-
I get the reference to the test_view,
testRootView = findViewById(R.id.test_view);
-
create SimpleExoplayerView programmatically
simpleExoPlayerView = new SimpleExoPlayerView(this);
-
subscribe to STATE_READY and when it received add simpleExoPlayerView to testRootView
if(playbackState == Player.STATE_READY) {
testRootView.addView(simpleExoPlayerView);
}
Also I added Meizu device name in MediaCodecVideoRenederer. Workaround method now looks like that:
private static boolean codecNeedsSetOutputSurfaceWorkaround(String name) {
// Work around https://github.com/google/ExoPlayer/issues/3236,
// https://github.com/google/ExoPlayer/issues/3355 and
// https://github.com/google/ExoPlayer/issues/3439.
return (("deb".equals(Util.DEVICE) || "flo".equals(Util.DEVICE))
&& "OMX.qcom.video.decoder.avc".equals(name))
|| (("tcl_eu".equals(Util.DEVICE) || "SVP-DTV15".equals(Util.DEVICE)
|| "BRAVIA_ATV2".equals(Util.DEVICE))
&& "OMX.MTK.VIDEO.DECODER.AVC".equals(name)
|| "M5c".equals(Util.DEVICE) && "OMX.MTK.VIDEO.DECODER.AVC".equals(name));
}
From what I see from debugging the code flow looks like that:
setSurface(Surface surface)
called with surface null, so we exit this function without doing anything.- We get in
onInputFormatChanged(Format newFormat)
with audio codec first. so we continue tomaybeInitCodec()
and exiting this function ok. - We get
onInputFormatChanged(Format newFormat)
once again. This time with video codec. And going intomaybeInitCodec()
shouldInitCodec()
returns true.surface != null
is false butshouldUseDummySurface(codecInfo.secure);
is true. So the statement is true.shouldUseDummySurface()
returns true. Here all the statements return true exceptDummySurface.isSecureSupported(context)
that returns false. but because of || sign it is enough that!codecIsSecure
return true for this statement to be also true.- So then we going into
configureCodec()
(all the workaround flags inmaybeInitCodec()
are set to false). inconfigureCodec()
the surface is null. Assertion not throwing exception. dummySurface instantiated.
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
- And from there we continue to
codec.start();
and Boom! exception thrown.
You say that dummySurface should never be created in a proper workaround mode. But in my case it happens to work in exact that way. Also the codec.start
is called not from setSurface
. Any idea for reason why it can happen? Note, that I in purpose reproduce this issue in your demo app with your drm content in order to be maximum aligned to your workspace. exoplayer branch is release-v2
It will be grate, if you add Meizu and Lenovo K4 devices to the list of excluded devices and push it on some side branch, that I can check if this fix apply for them. I am quite sure, that there is something that I am missing.
Here is the device names(same as appear in your Util.DEVICE)
Meizu M5C — M5c
Lenovo K4 Note — A7010a48
Thanks a lot for this detailed analysis! Not many people make this effort to help us debug a problem
It turns out that there is a difference I didn’t know about (thanks to @ojw28 for pointing this out). The original fix for other devices (#3439) included some further changes to prevent the DummySurface from being instantiated. Please have a look at this commit to see the details. I guess it will work when you add this change to your code (especially that shoulduseDummySurface
also checks for the workaround).
I’ll add the Meizu M5C and the Lenovo K4 to our list.
Thanks for your solution. I made the changes you suggest and it seems to work both on Meizu M5c and Lenovo K4 Note.
For some reason it did not work on Moto C+ that we tested on. When I print it Util.DEVICE
, I could see that the name is slightly differ from the one you provide.
You told that it is «panell_s» , but in my case the name was «panell_p». Probably there is some minor difference in devices, and therefore they have different names. Anyway, adding «panell_p» to the device list solved the issue.
What I am wondering now, is how many devices out there that we does not know about them having this problem. Is there more general solution in plan, then just excluding device-device? Also, I observed that all of the our problematic devices have same chipset and codec (just to take it in your consideration). Maybe there we can detect some patterns and exclude devices by them and not by name.
Another thing I want to ask you about, is your release plans. I am not asking for exact date, just want to know if for now I should think about some temporary solution, or just wait for your release.
Thank you very much for your support.
Yes, there is also panell_d, panell_dl and panell_dp. Guess I better change it to include all devices starting with «panell» then.
We also discussed the same question — whether we should enable the workaround for certain API levels and decoders for all devices or something similar. Because we also don’t know for sure how many devices out there have this problem. Using the chipset may be a good idea, need to think about this a little bit further.
For our release plans, there is probably a new release in the next couple of days.
Thanks again.
I was thinking about possible solutions, and came to a little bit different possible approach. If you provide some sort of Settings API that can give application (me) ability to decide if I want this workaround or not for example: player.useDummySurfaceWorkaround(true)
, I can catch this specific exception once and enable workaround for all previous sessions for this device. This will release you from responsibility of tracking all the problematic devices and adding them to the endless workaround list. On my side I can also relax and forget about this bug
The only thing I am worried about is this exception unique for this sort of behaviour, or it can be thrown in some other circumstances?
This problem often results in the application not responding on these devices instead of an exception. Especially when switching between two real surfaces. That means we can’t just always try first and enable the workaround as soon as it fails.
If you want to catch the exception and then set a flag in your app, you can still do so by overriding shouldInitCodec
in MediaCodecVideoRenderer
to disable initializing the dummy surface if surface == null
. This extended renderer can then be used in ExoPlayer by overriding the buildVideoRenderers
in DefaultRenderersFactory
to return your renderer. And then pass in this renderers factory to ExoPlayerFactory.newSimpleInstance
.
ojw28
pushed a commit
that referenced
this issue
Feb 16, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 16, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 20, 2018
ojw28
pushed a commit
that referenced
this issue
Feb 20, 2018
Hi @tonihei and @ojw28, thank you for fixing this issue.
I want to express my concerns about the «device-specific workaround» approach.
What we did (I work with @AntonAFA) is the following:
- A customer has reported this issue on Moto C+ and Lenovo K4 Note
- We wanted to reproduce the issue locally, so we looked online for devices we can buy that have the same chipset as those devices (MT6737 and MT6753, respectively). The reported devices don’t sell here, and it was sort-of a shot in the dark.
- We found that Meizu M5c has the same chipset as the Moto C+, so we bought it and easily reproduced the issue.
But there are many other phones with the same chipset — we just chose one that was easy to get. So either it was just a lucky guess, or all those other phones (which are not explicitly named by ExoPlayer) will also fail.
In addition — as mentioned above, the Lenovo K4 Note has a different MediaTek chipset (albeit in the same family, MT67xx), and it fails in the same way.
Just my 2 cents.
We agree that the current approach isn’t doing a good job of targeting all affected devices. Although on the plus side, it’s likely that we’re targeting the popular ones; there are probably quite a lot of devices that barely anyone is using.
An approach that targets the chipset would be preferable, but I’m not sure how to do that. I don’t think there’s anything suitable in Build. Do you have any idea how we’d be able to target the workaround to a specific chipset?
Hi @ojw28,
From what I found, the best (read: least bad) source of the chipset id is android.os.SystemProperties.get("ro.board.platform")
(a private API, which is why it’s bad). For the Meizu M5c it gives me mt6737m
.
I don’t know why the extra «m»; probably a variant.
I’d read it into a static final field and query when required (maybe even create a «workaround-map»).
At the end of the day, it’s a matter of choosing between two hacks, so pick your poison. Using the chipset is more robust IMHO because I’m pretty sure that all devices with the same chipset have the same MediaCodec issues (also think about the adaptation workaround (#3257), which is required on some Exynos devices but not on MediaTek).
Being a Googler, can you reach out to the Android people and ask them to add the chipset id to android.os.Build
? Moreover, maybe Google should maintain a public device properties/capabilities db.
As for device popularity — we have a large customer in India; even unpopular, cheap, devices can have a few tens of thousands of users.
Hello team. As was previously discussed on this thread, we made some sort of workaround test, that checks and gather potentially codec problematic devices. Those in order to report you and make exoplayer better.
The workaround is pretty straight forward (as referenced here by @noamtamim https://github.com/kaltura/playkit-android/blob/2e58d94c0c9e2b962e9f31699f1f1c2b07d80790/playkit/src/main/java/com/kaltura/playkit/player/MediaCodecWorkaroundTest.java).
Before actually playing real content we first instatiate «test» player with local asset and dummy drm license. We listen for the Player events which should indicate us, if media with drm was managed to play on the device. Receiving of
MediaCodecRenderer.DecoderInitializationException
will indicate us that combination of the device specification and codec might be problematic. So we gather this device info and raise some flag that will make your codecNeedsSetOutputSurfaceWorkaround()
return true.
The problem we face now, is that amount of «problematic» devices that was collected by this test is huge. So I believe, that our test covers to much use-cases and probably we should somehow narrow/filter MediaCodecRenderer.DecoderInitializationException
by its cause. Can you help us with this filter by explaining which reasons for MediaCodecRenderer.DecoderInitializationException
might be relevant for us?
As I see there are only 3 reasons where this exception might be thrown
- When
DecoderQueryException
is thrown - When codecInfo is null in
maybeInitCodec
block - And when trying to configure codec in the same block by calling
configureCodec(codecInfo, codec, format, wrappedMediaCrypto);
Will appriciate your response on the subject
I tried using your test code and the assets (mp4+mp4+init data) and also get workaroundRequired = true
for a device which should not need the workaround.
Could it be that all devices are labelled as needing the workaround with this approach? Or am I missing something?
No, we label device as needed workaround only when we get MediaCodecRenderer.DecoderInitializationException
. Probably there might be additional reasons for getting thes exception. And thats what I am trying to figure out. On which device did you run the test?
I used a Nexus 6P and got a DecoderInitializationException as well. I fear that the workaround test doesn’t cover the real thing because it does never switches (or sets) surfaces and probably fails for other reasons.
What was the cause fot this DecoderInitializationException
? Can you suggest some more convinient way of doing that test? Maybe, ad some «setSurface» block?
After looking into this in more detail, I think setting the surface shouldn’t be necessary because the DummySurface is still created (as you don’t set a surface at all). It just wouldn’t catch devices which only have problems with switching surfaces but that’s probably fine for the first try.
However, it seems the test content is too small. The reason is fails for me is «Unsupported WxH = (32)x(32) supported range is min(64)x(64) — max(4096)x(4096)». When you look at the failing stack traces, you’ll notice that it fails in MediaCodec.configure
and not in MediaCodec.start
as in the stack trace above in your first post.
@tonihei the problem is that at the time the test runs, we don’t have a license URL that will respond correctly. Are you saying that when you set this proxy URL the response it provides (which is obviously not a valid license response) is good enough? What if I’ll be offline at the time of testing?
More importantly, the idea for the fakeDrmCallback with a delay of 10 seconds is making sure the license will not fail before the test reaches a conclusion.
In other words — the test works for you on a device that really shouldn’t be problematic (shouldn’t be listed in the workaround list). But I suspect it will also skip the real culprits (such as Meizu 5c).
The fakeDrmCallback
doesn’t work because the player just waits for 10 seconds and then issues an IllegalArgumentException because the key response is null.
To get a valid Widevine license (which allows to setup the secure surface), you either need the online license request or you manage to obtain an offline license which never expires.
Alternatively, [thanks to @AquilesCanta for pointing this out], you can use ClearKey to provide the key directly in the media. This should allow you to run the test offline.
Unfortunately, I don’t have one of the failing devices available at the moment. So I can’t confirm whether the test with the real drm callback actually fails.
Final remark: You should probably also release the test player for all other errors which are not a DecoderInitializationException to prevent resource leaking.
- I considered a license that never expires (I can create such a thing in our DRM server), but this license is still bound to the device that created the request — so it’s not something I can hold as an asset
- ClearKey would be nice, but I’m pretty sure it’s only supported from Android 7.1 and up. We need to support 4.3.
- I don’t need the license request to succeed, because I don’t really intend to play the file. That’s the point of the fakeDrmCallback: I want to give the renderer a chance to fail because of the DummySurface issue before it fails for an invalid response.
I want to give the renderer a chance to fail because of the DummySurface issue before it fails for an invalid response.
The problem is that the player never reaches the READY state in such a setup. Instead, after 10 seconds waiting, it gets the wrong key request answers and fails with a DrmSessionException. If I understand you correctly, that’s what you wanted. Waiting for the READY state is then probably not the right way to «pass» the test.
When you say the number of problematic devices is huge — how do you determine that a device is problematic? Do you count the number of positive and negative examples of this workaround test? If so, you should be able to filter by flaky decoder initialization problems for other reasons. This problem should be reproducible 100% of the time, so there shouldn’t be a single passing device of the problematic ones.
Hi @tonihei,
We don’t ever expect the player to be READY. However, we do expect that if it failed with DecoderInitializationException
, it will be because of the DummySurface
issue:
if (error.getCause() instanceof MediaCodecRenderer.DecoderInitializationException) { workaroundRequired = true; }
Putting it all together, I suspect that the only reason for the huge amount of false positives is the video size. Am I right?
BTW, in the released version we did move the player.release()
call outside of the if
.
Yes, that seems fine. I think I got quite confused that your example code set workaroundRequired = false
when READY was reached which clearly wouldn’t work.
And yes I agree, that to some extent the failures were due to the video size. Please note that there will be other DecoderInitialization failures for various reasons and you’ll still need to check that the test fails for all devices of the same model.
Thanks for reporting! That really is a never-ending-story ;(
Do you have the Build.MODEL for that? It might be «CAG-L02» or «CAG-L22».
The Build.MODEL is listed as «gobo», but I don’t think it’s a real value. The tested device was not yet released at the time (TAGS=dev-keys), so all the values look strange:
"BRAND": "google",
"MODEL": "gobo",
"MANUFACTURER": "alps",
"TAGS": "dev-keys",
"FINGERPRINT": "google/gobo/gobo:8.1.0/OMB1.171031.003/4428322:user/dev-keys",
The device was released since, but I don’t have anyone that can check on a production device.
The chipset is MT6737M — the same as some other devices listed above.
@tonihei / others — does Google have a database of all the certified Android devices, that contain everything from android.os.Build?
Thanks @tonihei, I didn’t know about this list. Regarding the device, they both use the same chipset, and the issue is there.
Do you also have the culprit decoder name? Forgot to ask about it.
No, sorry. I don’t have the device itself with me.
Let’s dupe this onto #4468, which is newer, but provides a more comprehensive list of (possibly) affected devices. We can use that for tracking.
I think we’ll also go ahead and make codecNeedsSetOutputSurfaceWorkaround
and codecNeedsDummySurfaceSurfaceWorkaround
protected and non-static, as was suggested here.
google
locked and limited conversation to collaborators
Nov 23, 2018