LINUX.ORG.RU

Сообщения gobot

 

segfault и прочие read access

Так и знал, что кодя на с-подобных столкнусь с этой ****. На ровных местах вылезает ошибка «доступ к памяти». Какая то переменная где-то кем-то удалилась и не может быть прочитана в другом месте.

Есть вот такая чепуха, которая в треде парсит логи на предмет ошибок и прочего

//lambda - вызывается тредом, передает локальную переменную строку
[](std::string line){
  if (std::regex_search(line, std::regex(".*(some err).*"))) debug();
  if (std::regex_search(line, std::regex(".*(some err2).*"))) debug();
  if (std::regex_search(line, std::regex(".*(some err3).*"))) debug();
  //...
}


Когда тред каким-то образом убивается (в моем случае это в основном при выходе из программы) вылезают ошибки доступа к памяти. По call-stack вижу что где то далеко в std::regexp (где то в 18 хопе вверх от моего вызова регекса). Как я понимаю, в regex_search() переменная далее идет по цепочке вызовов и в ккакой то момент она удаляется. Вот как такое предотвратить? Ведь на момент вызова regex_search() переменная существовала? Как я понимаю это из-за того что переменная локальная? Когда тред завершается принудительно переменная удаляется.

Может быть сделать некий конвеер, чтобы не локальную переменную передавать? Как лучше сделать, чтобы избежать такого?

 ,

gobot
()

С++ удаляет локальные переменные

Узнал ужасную вещь. С++ удаляет локальные переменные.
Допустим создал я объект

Myclass xxx;
xxx.onready = func
xxx.start();

Создался объект, запустил start... Иии... Умер. Потом с++ запускает деструктор объекта. А мой колбек onready не дождется своего выхода.
Это нормально? Я же сам не удалял объект через delete. То есть получается компилятор сам за меня решает?

 

gobot
()

Выучил c++: как внедрить в бинарь свой код

Выучил я с++ и написал программу.

Теперь осталось запаковать ее и сделать первый выпуск.

Вот что я хочу: хочу, чтобы в бинарном файле можно было изменить строку. То есть бинарник будет как бы именным, с неким штампом, подписью, токеном. Я хочу типа регекспом искать в бинарнике некую строку и заменять ее на уникальную. Ну типа логина. Строка это будет например char name[10] = «holderxxxx». Вот мне этот holderxxxx нужно заменять на реальное значение, чтобы потом в коде вывести «привет name»

Как такое сделать?

 ,

gobot
()

C++ адрес подменяется

Продолжаю изучать с++

Process* ffplay = nullptr; //указатель в 0
ffplay = new Process("xxx"); //возвращается адрес  0x00000000003aa270 и заполняется память
ffplay->Start(); //тут запускается дочерний процес и также новый thread, который читает трубу процесса

delete ffplay; //освобождаю память
ffplay = nullptr; //указываю на адрес памяти 0x0000000000000000

//далее, в триде, проверяется что объект убит (это можно определить по свойствам объекта, например там id будет -12334214, а у созданого объекта 1..2..3...) и все поля либо NULL, ну в общем понятно. 

//трид успешно завершается, говорит что объект более не живучий и выхожу из цикла чтения. Ну либо когда труба закрыта

//стоит мне после этого создать новый объект на старый указатель
ffplay = new Process("xxx"); //тут снова 0x00000000003aa270

//то потом тред не завершается, потому что считает что объект все ещё живой. Это что получается, быстренько записали на старый адрес новые данные и тред даже не знает что ему подменили объект?

//если следом создать ещё один
Process *ffplay2 = new Process("xxx"); //тут адрес уже другой 0x000000000022d6b0


Как мне избежать такой подмены объекта в треде?

 , ,

gobot
()

c++ Вопросик с лямбда

Продолжаю изучать с++ ) Загвоздка с лямбда


class Process {
public:

  int (*onReady)(const char*);  
  std::string outpurBuffer;
}

Process *proc = new Process();
proc->onReady = [](const char* reason) {
  std::string = proc->outpurBuffer;
  return 1;
};


Не работает, говорит что локальную переменную нельзя. Гуглю соответственно «c++ local variable in lambda», первый пример указывает что нужно в скобки квадратные передавать Captured variables

// Local Variables
std::string msg = "Hello";
int counter = 10;
// Defining Lambda function and
// Capturing Local variables by Value
auto func = [msg, counter] () {
                          //...
                          };

ок, делаю
proc->onReady = [proc](const char* reason) {
  std::string s = proc->outpurBuffer;
  return 1;
};

Снова ошибка, но уже с приведением типов. Что не так?

Кстати сразу другой вопросик, чем отличается
const char* reason;
const char *reason;

Есть ли разница? Компилятору я смотрю без разницы, то и то проглатывает

 ,

gobot
()

Как писать под ios не имея мака

Неужели у орды фрилансеров у всех маки за пару сотен руб?

Почему под винь и линь и макь есть андроид студия, а под гребаный иос нет?

Как мне написать хеловорлд без покупки мака?

 , , ,

gobot
()

С++ вопросик про ссылку на фукнцию

Продолжаю изучать с++, запутался в указателях, а в гугле не могу правильно составить запрос. Мне нужно определить в структуре ссылку на функцию onBuffer, чтобы потом созданный thread ее вызывал. Как простой int передать я понял, а вот как функцию? Пробовал уже и слева и справа * ставить и & b и так и сяк )


int onBuffer(const char* data){
   
}

typedef struct ThreadPar {
    int sdtOut;      
    int *onBuffer; //как определить?
} ThreadPar, *PThreadPar;


PThreadPar ThreadParameters;
ThreadParameters->sdtOut = sdtOutRd;
ThreadParameters->onData = onBuffer; //как передать?

 ,

gobot
()

Вопросик по C++ NULL

Я тут изучаю с++ ) Не могу понять как мне проверить что объект создан?

Process{
  public:
    Process(const char* cmd_){}
  ...
}


далее я объявляю
Process ffplay=NULL;

if(ffplay){} //ошибка
//conditional expression of type 'Process' is illegal

if(ffplay != NULL && !ffplay.isClosed()){} //ошибка
//binary '!=': no operator found which takes a left-hand operand of type 'Process' (or there is no acceptable conversion)



ffplay ведь изначально NULL(=0)

 ,

gobot
()

Сборка оптимизированного ffmpeg

Начинаю тут(пришлось) потихоньку компилировать в с\с++. Хочу скомпилировать(собрать) оптимизированный(по размеру) статичный ffmpeg. Все хорошо собирается, статичный бинарь получается около 2 мб. Но стоит мне добавть SDL2, чтобы собрать ffplay, сборка проходит нормально, но при запуске вылазит ошибка что не может найти либу libwinpthread-1.dll. В документации ffmpeg по сборке mingw говорится что это якобы кривой gcc добавляет эту либу, вне зависимости от параметров сборки.

https://trac.ffmpeg.org/wiki/CompilationGuide/MinGW

Unfortunately the gcc.exe it provides seems to create binary's that require files like «libgcc_s_dw2-1.dll» and «libwinpthread-1.dll» (etc.?) to accompany your executable, so can cause some difficulty there. You can remove some files to remove dependencies on things like «libbzip2.dll» see ​https://ffmpeg.zeranoe.com/forum/viewtopic.php?f=5&t=3688 and possibly avoid the libgcc.dll requirement by using "-static" at linking time.

и предлагает удалить какие то файлы, которые вызывают эти зависимости. Какие именно файлы не уточняется и указывается ссылка на домен ffmpeg.zeranoe.com который сейчас не доступен (искал в кеше, не нашел)

Как бы мне избавиться от этой libwinpthread?

ldd ffmpeg.exe
libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll


Собираю так

( читать дальше... )

 ,

gobot
()

Собрать все dll в один бинарь

Делаю программу на libavcodec, она цепляет avcodec.dll и прочие. Я хочу один бинарь, так как не удобно таскать dll всюду. Можно ли такое? Или нужно добавлять в проект весь исходный код ffmpeg и сомпилировать?

 , ,

gobot
()

Изменение SPS на лету через libavcodec

Можно ли как нибудь менять в потоке NAL unit? Мне нужно подменять параметр в sps, seq_id. Без рекодирования, конечно... Хотелка экзотическая, но это пока способ решить проблему

Что заставляет кодировщик часто генерировать SPS\PPS?

 ,

gobot
()

Вопросик по C++

Я дебажу chromium, хочу добавить в класс свой метод для теста. Класс DXVAVideoDecodeAccelerator наследник класса VideoDecodeAccelerator. Я хочу добавить в DXVAVideoDecodeAccelerator публичный метод InsertFrame().

Что я делаю
media/video/video_decode_accelerator.h

class MEDIA_GPU_EXPORT DXVAVideoDecodeAccelerator
    : public VideoDecodeAccelerator {
 public:


 void InsertFrame(int32_t picture_buffer_id, int64_t ts);
}




media/video/video_decode_accelerator.cc
void DXVAVideoDecodeAccelerator::InsertFrame(int32_t picture_buffer_id, int64_t ts)  {
  DVLOG(1) <<  picture_buffer_id << ":" <<  ts;
}


Далее в коде я вызываю
vda_->InsertFrame(picture.picture_buffer_id(), timestamp.InMicroseconds());


и выдает ошибку
error: no member named 'InsertFrame' in 'media::VideoDecodeAccelerator'


Обязательно ли декларировать этот метод в родительском классе VideoDecodeAccelerator? Если да, то печально, этот инклуд затрагивает много кода и пересборка часа 3 будет наверное... Как наиболее просто можно добавить в DXVAVideoDecodeAccelerator этот метод?


Вот исходники
https://source.chromium.org/chromium/chromium/src/ /master:media/gpu/windows/...
https://source.chromium.org/chromium/chromium/src/ /master:media/video/video_...

 ,

gobot
()

Что заставляет кодировщик часто генерировать SPS\PPS?

Хочу записывать mp4 из webrtc стрима. Проблема в том, что кодировщик chrome почему то слишком часто (с каждым IDR) посылает ещё и SPS\PPS пакеты. Парсил и сравнивал эти SPS\PPS, они все одинаковые (за исключением битов выравнивания в конце rbsp_alignment_zero_bit). Разрешение в потоке идет постоянное, не изменяется

Вот пример двух SPS https://www.diffchecker.com/rABX2dvT


Смотрел другие видео, везде SPS посылается один, в начале видео. В моем же случае они сыпятся с каждым IDR

Вот примерный порядок NAL (вырезал nal_unit_type=1, т.к. их слишком много)

nal_unit_type     00111 = 7 (SPS)
nal_unit_type     01000 = 8 (PPS)
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5 (IDR)
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7
nal_unit_type     01000 = 8
nal_unit_type     00101 = 5
nal_unit_type     00111 = 7

Последовательность такая SPS PPS IDR, SPS PPS IDR, SPS PPS IDR... Ничего не понимаю, зачем слать каждый раз SPS, если он не меняется. Что ещё может меняться в стриме, что заставляет кодировщик слать эти SPS?

Не охота пока дебажить хром, может кто подскажет куда копать )

 , ,

gobot
()

Вопросик по ld

Собрал вот такую либу rtcConn.node

g++ -shared -pthread -rdynamic -m64 -z noexecstack -z relro -Wl,-soname=rtcConn.node -o Debug/obj.target/rtcConn.node -Wl,--start-group Debug/obj.target/rtcConn/addon.o Debug/obj.target/rtcConn/WebRtcConnection.o Debug/obj.target/rtcConn/ThreadPool.o Debug/obj.target/rtcConn/IOThreadPool.o Debug/obj.target/rtcConn/MediaStream.o Debug/obj.target/rtcConn/conn_handler/WoogeenHandler.o Debug/obj.target/rtcConn/erizo/src/erizo/DtlsTransport.o Debug/obj.target/rtcConn/erizo/src/erizo/IceConnection.o Debug/obj.target/rtcConn/erizo/src/erizo/LibNiceConnection.o Debug/obj.target/rtcConn/erizo/src/erizo/SdpInfo.o Debug/obj.target/rtcConn/erizo/src/erizo/SrtpChannel.o Debug/obj.target/rtcConn/erizo/src/erizo/Stats.o Debug/obj.target/rtcConn/erizo/src/erizo/StringUtil.o Debug/obj.target/rtcConn/erizo/src/erizo/WebRtcConnection.o Debug/obj.target/rtcConn/erizo/src/erizo/MediaStream.o Debug/obj.target/rtcConn/erizo/src/erizo/lib/LibNiceInterfaceImpl.o Debug/obj.target/rtcConn/erizo/src/erizo/thread/IOThreadPool.o Debug/obj.target/rtcConn/erizo/src/erizo/thread/IOWorker.o Debug/obj.target/rtcConn/erizo/src/erizo/thread/Scheduler.o Debug/obj.target/rtcConn/erizo/src/erizo/thread/ThreadPool.o Debug/obj.target/rtcConn/erizo/src/erizo/thread/Worker.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/PacketBufferService.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/RtcpForwarder.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/RtcpProcessorHandler.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/RtpUtils.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/QualityManager.o Debug/obj.target/rtcConn/erizo/src/erizo/rtp/RtpExtensionProcessor.o Debug/obj.target/rtcConn/erizo/src/erizo/dtls/DtlsSocket.o Debug/obj.target/rtcConn/erizo/src/erizo/dtls/DtlsClient.o Debug/obj.target/rtcConn/erizo/src/erizo/dtls/bf_dwrap.o Debug/obj.target/rtcConn/erizo/src/erizo/pipeline/Pipeline.o Debug/obj.target/rtcConn/erizo/src/erizo/stats/StatNode.o -Wl,--end-group -L/owt-server/source/agent/webrtc/rtcConn/../../../../build/libdeps/build/lib -lsrtp2 -lssl -ldl -lcrypto -llog4cxx -lboost_thread -lboost_system -lnice


Эти строчки указывают на то, что подключаемые библиотеки лежат в папке ...build/lib и нужно прилинковать либу ssl
-L/owt-server/source/agent/webrtc/rtcConn/../../../../build/libdeps/build/lib
-lssl


Я потом смотрю
ldd rtcConn.node
        linux-vdso.so.1 (0x00007fff90ff4000)
        libssl.so.1.1 => /usr/lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007f4cbdf50000)
        libcrypto.so.1.1 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007f4cbda85000)
        liblog4cxx.so.10 => /usr/lib/x86_64-linux-gnu/liblog4cxx.so.10 (0x00007f4cbd6bc000)
        libboost_thread.so.1.65.1 => /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 (0x00007f4cbd497000)
        libboost_system.so.1.65.1 => /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 (0x00007f4cbd292000)
        libnice.so.10 => not found
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4cbcf09000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4cbcb6b000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4cbc953000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4cbc734000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4cbc343000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4cbe549000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4cbc13f000)
        libapr-1.so.0 => /usr/lib/x86_64-linux-gnu/libapr-1.so.0 (0x00007f4cbbf0a000)
        libaprutil-1.so.0 => /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0 (0x00007f4cbbcdf000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f4cbbad7000)
        libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f4cbb8d0000)
        libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f4cbb698000)
        libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f4cbb466000)


и вижу что libssl берется вообще из /usr/lib/, хотя должно быть из ...build/lib. Почему так?

 , ,

gobot
()

Как отдебажить либу с++?

Я скомпилил либу libwebrtc.a с включенным дебагом. Эта либа используется в node.js(загружается через addon). Как мне ее отдебажить, имея Visual Studuo и Windows 7? Или через любые другие инструменты? Или такое возможно только используя linux?

 , ,

gobot
()

Найти баг в стриме mp4\h264

Я кодирую поток mp4\flv\h264

Все хорошо, но только в chromium видео затыкается (останавливается) случайным образом на Х секунде, только если включено hardware acceleration.

Нужно понять почему. В хром был написал багрепорт, но пока они его разберут может пройти много времени, на мой взгляд проще изменить кодировщик.

Задача 1: найти баг в кодировщике
ЛИБО
Задача 2: найти баг в хроме

Если найдутся спецы буду рад

Ссылки по теме:
Монотонный DTS
Как отдебажить GPU?
Видео замораживается на 7 секунде

Проблемное видео (останавливается на 7 сек., одно из... это просто пример):
https://bugs.chromium.org/p/chromium/issues/attachment?aid=459480&signed_...


Цену не знаю, предлагайте сами

 , , , ,

gobot
()

Монотонный DTS

Не могу разобраться с monotonous DTS в h264. Ffmpeg ругается, что DTS увеличивается не монотонно. Также сыпятся сообщения из libx264: non-strictly-monotonic.


ffmpeg -y -loglevel repeat+info -i bad_7s.mp4 -vsync 0 out.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'bad_7s.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.12.100
  Duration: 00:01:04.33, start: 0.000000, bitrate: 1656 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 480x270, 1654 kb/s, 24.42 fps, 16k tbr, 16k tbn, 32k tbc (default)
    Metadata:
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x6473e80] using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX
[libx264 @ 0x6473e80] profile High, level 2.1
[libx264 @ 0x6473e80] 264 - core 155 r2901 7d0ff22 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.12.100
    Stream #0:0(und): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 480x270, q=-1--1, 24.42 fps, 1571k tbn, 24.42 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.18.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 0, current: 0; changing to 1. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 192993, current: 192993; changing to 192994. This may result in incorrect timestamps in the output file.
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 321655, current: 321655; changing to 321656. This may result in incorrect timestamps in the output file.
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 771972, current: 771972; changing to 771973. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 900634, current: 900634; changing to 900635. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 1029296, current: 1029296; changing to 1029297. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 1157958, current: 1157958; changing to 1157959. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 1415282, current: 1415282; changing to 1415283. This may result in incorrect timestamps in the output file.
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[libx264 @ 0x6473e80] non-strictly-monotonic PTS
[mp4 @ 0x6475540] Non-monotonous DTS in output stream 0:0; previous: 1801268, current: 1801268; changing to 1801269. This may result in incorrect timestamps in the output file.



Как я понял, DTS должен увеличиваться (что логично). Посмотрел исходники libx264 https://code.videolan.org/videolan/x264/-/blob/master/encoder/encoder.c#L3325

 if( h->param.b_vfr_input && fenc->i_pts <= h->frames.i_largest_pts )
            x264_log( h, X264_LOG_WARNING, "non-strictly-monotonic PTS\n" );



из чего следует(по моей логике), что если текущий PTS меньше или равен предыдущему (точнее самому большому значению всех предыдущих PTS?), то выводится предупреждение

Распарсил свой видеоролик
ffprobe -show_frames -select_streams v:0  bad_7s.mp4


И не увидел там плохих DTS\PTS(они всегда равны в моем случае). Я даже написал простой скрипт, который бы находил эти «плохие» DTS

Выгрузил в json информацию о всех фреймах
 
ffprobe -show_frames -select_streams v:0 -print_format json  bad_7s.mp4 > frames.json


node parse.js
const fs = require("fs");

var data = JSON.parse(fs.readFileSync("frames.json").toString());

var largest_dst;
for(var item of data.frames){
    var dts = item.pkt_dts;
    var pts = item.pkt_pts;

    if(dts !== pts) {
        console.error("error", item);
        process.exit();
    }

    if(largest_dst && dts <= largest_dst){
        console.error(item);
    }

    if(!largest_dst || dts > largest_dst){
        largest_dst = dts;
    }

}


...и скрипт не нашел ничего, вывод пустой. Все DTS увеличиваются!

Что я делаю\понимаю не так?

Все фреймы в формате csv
https://pastebin.com/B9DtFsPR

 , , , ,

gobot
()

Как отдебажить GPU?

У меня в браузере Хром не понятно работает декодирование h264 некоторых видео, с включенным hardware acceleration. Как я понимаю (из логов chrome://media-internals/), хром при рендеринге(и демультиплексировании?) использует DXVA, тобишь DirectX (да, я тестирую на Windows 7)

Собственно проблема в том, что видео останавливается на некотором участке времени (иногда случайным образом, иногда стабильно на X секунде). Если отключить аппаратное ускорение, то проблема исчезает. Также такие видео нормально воспроизводят нативные плееры и другие браузеры (Лиса, Андроид), просто на секунду затыкаются, но воспроизведение продолжает идти дальше (в хроме тупо останавливается с ошибкой DECODER_UNDERFLOW)

Пытался собрать Chromium, скачал около 50Гб исходников, думал собрать дебажную версию и смотреть логи, но сборка не удалась, т.к. мало опыта с Visual Studio

Я правильно понимаю, что h264 декодирует системная либа DirectX? Если так, то как посмотреть лог этого декодирования и понять причину остановки?

Вот лог chrome://media-internals

Timestamp	Property	Value
00:00:00.000	origin_url	"file:///"
00:00:00.000	kFrameUrl	"file:///C:/Downloads/bad_7s.mp4"
00:00:00.000	kFrameTitle	""
00:00:00.000	url	"file:///C://Downloads/bad_7s.mp4"
00:00:00.006	kTotalBytes	13321640
00:00:00.006	kIsStreaming	false
00:00:00.006	kIsSingleOrigin	true
00:00:00.006	kIsRangeHeaderSupported	true
00:00:00.007	pipeline_state	"kStarting"
00:00:00.018	info	"FFmpegDemuxer: created video stream, config codec: h264, profile: h264 baseline, level: not available, alpha_mode: is_opaque, coded size: [480,270], visible rect: [0,0,480,270], natural size: [480,270], has extra data: true, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:SMPTE170M, transfer:SMPTE170M, matrix:SMPTE170M, range:LIMITED}"
00:00:00.018	kAudioTracks	[]
00:00:00.018	kVideoTracks	[{"alpha mode":"is_opaque","codec":"h264","coded size":"480x270","color space":"{primaries:SMPTE170M, transfer:SMPTE170M, matrix:SMPTE170M, range:LIMITED}","encryption scheme":"Unencrypted","has extra data":true,"hdr metadata":"unset","natural size":"480x270","orientation":"0°","profile":"h264 baseline","visible rect":"0,0 480x270"}]
00:00:00.018	kMaxDuration	64.331
00:00:00.018	kStartTime	0
00:00:00.018	kBitrate	1656637
00:00:00.018	error	"{\"causes\":[{\"causes\":[],\"data\":{},\"stack\":[{\"file\":\"../../media/filters/decrypting_video_decoder.cc\",\"line\":53}],\"status_code\":264,\"status_message\":\"\"}],\"data\":{\"Decoder name\":\"DecryptingVideoDecoder\"},\"stack\":[{\"file\":\"../../media/filters/decoder_selector.cc\",\"line\":172}],\"status_code\":265,\"status_message\":\"\"}"
00:00:00.039	info	"Starting Initialization of DXVAVDA"
00:00:00.040	info	"Using D3D9 device for DXVA"
00:00:00.060	kIsVideoDecryptingDemuxerStream	false
00:00:00.060	kVideoDecoderName	"MojoVideoDecoder"
00:00:00.060	kIsPlatformVideoDecoder	true
00:00:00.060	info	"Selected MojoVideoDecoder for video decoding, config: codec: h264, profile: h264 baseline, level: not available, alpha_mode: is_opaque, coded size: [480,270], visible rect: [0,0,480,270], natural size: [480,270], has extra data: true, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:SMPTE170M, transfer:SMPTE170M, matrix:SMPTE170M, range:LIMITED}"
00:00:00.060	pipeline_state	"kPlaying"
00:00:00.086	dimensions	"480x270"
00:00:00.086	kResolution	"480x270"
00:00:00.129	video_buffering_state	{"state":"BUFFERING_HAVE_ENOUGH"}
00:00:00.129	pipeline_buffering_state	{"for_suspended_start":false,"state":"BUFFERING_HAVE_ENOUGH"}
00:00:00.129	info	"Effective playback rate changed from 0 to 1"
00:00:00.129	event	"kPlay"
00:00:00.775	info	"Starting Initialization of DXVAVDA"
00:00:00.775	info	"Using D3D9 device for DXVA"
00:00:00.840	info	"Starting Initialization of DXVAVDA"
00:00:00.841	info	"Using D3D9 device for DXVA"
00:00:00.018	duration	64.331
00:00:04.070	info	"Starting Initialization of DXVAVDA"
00:00:04.071	info	"Using D3D9 device for DXVA"
00:00:06.488	info	"Starting Initialization of DXVAVDA"
00:00:06.489	info	"Using D3D9 device for DXVA"
00:00:07.359	video_buffering_state	{"reason":"DECODER_UNDERFLOW","state":"BUFFERING_HAVE_NOTHING"}
00:00:07.359	pipeline_buffering_state	{"for_suspended_start":false,"reason":"DECODER_UNDERFLOW","state":"BUFFERING_HAVE_NOTHING"}


Как видно из лога, Хром выбирает видео декодер MojoVideoDecoder, это и есть hardware acceleration, потом идут бесконечные «Starting Initialization of DXVAVDA», тоже не понятно почему. На других видео такого нет. В итоге видео останавливается на 7 сек. Пишет что якобы в декодере нет данных для обработки, хотя все видео забуферезировалось в плеере (1 минута)


Пример видео, которое останавливается на 7 сек.
https://bugs.chromium.org/p/chromium/issues/attachment?aid=459480&signed_...

 , , , ,

gobot
()

Видео замораживается на 7 секунде

Есть видео h264 Constrained Baseline 3.0 yuv420p(progressive, left), 480x270, ~30fps, duration: 1:04, без звука

Если открыть в Google Chrome при включенном аппаратном ускорении, то видео останавливается на 7 секунде (без ускорения задерживается на пол секунды и продолжает играть). Также если открыть в плеере, например MPC - тоже скачек на 7 сек.

В конце лога хром выдает DECODER_UNDERFLOW и все.
Прогонял через ffmpeg и ffprobe, ошибок никаких нет
Пробовал смотреть пакеты через ffprobe - ничего не дало

Чем дебажить? Что может быть? В какую сторону копать? Все уже перерыл не пойму в чем причина

chrome://media-internals/

00:00:00.394	info	"Selected MojoVideoDecoder for video decoding, config: codec: h264, profile: h264 baseline, level: not available, alpha_mode: is_opaque, coded size: [480,270], visible rect: [0,0,480,270], natural size: [480,270], has extra data: true, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:SMPTE170M, transfer:SMPTE170M, matrix:SMPTE170M, range:LIMITED}"
00:00:00.395	pipeline_state	"kPlaying"
00:00:00.432	dimensions	"480x270"
00:00:00.432	kResolution	"480x270"
00:00:00.467	video_buffering_state	{"state":"BUFFERING_HAVE_ENOUGH"}
00:00:00.467	pipeline_buffering_state	{"for_suspended_start":false,"state":"BUFFERING_HAVE_ENOUGH"}
00:00:00.467	info	"Effective playback rate changed from 0 to 1"
00:00:00.467	event	"kPlay"
00:00:00.338	duration	64.331
00:00:01.117	info	"Starting Initialization of DXVAVDA"
00:00:01.118	info	"Using D3D9 device for DXVA"
00:00:01.177	info	"Starting Initialization of DXVAVDA"
00:00:01.178	info	"Using D3D9 device for DXVA"
00:00:04.411	info	"Starting Initialization of DXVAVDA"
00:00:04.412	info	"Using D3D9 device for DXVA"
00:00:06.828	info	"Starting Initialization of DXVAVDA"
00:00:06.829	info	"Using D3D9 device for DXVA"
00:00:07.697	video_buffering_state	{"reason":"DECODER_UNDERFLOW","state":"BUFFERING_HAVE_NOTHING"}
00:00:07.697	pipeline_buffering_state	{"for_suspended_start":false,"reason":"DECODER_UNDERFLOW","state":"BUFFERING_HAVE_NOTHING"}



Само видео

https://bugs.chromium.org/p/chromium/issues/attachment?aid=459480&signed_...


Перемещено leave из development

 , , ,

gobot
()

Видео останавливается когда загружаю маленькими порциями через MSE

Экспериментирую с Media Source Extension, основу взял из https://developers.google.com/web/updates/2016/03/mse-sourcebuffer


  • Загружаю видеоролик через XMLHttpRequest
  • Разбиваю его на 20 кусочков через Blob & FileReader (1 кусок примерно 3 сек.)
  • Создаю MediaSource и добавляю в него буфер
  • Добавляю в буфер эти кусочки



Кусочки добавляю не сразу все, а один за другим, а именно когда в video опустошается буфер, то есть наступает событие waiting.


  • После загрузки файла и разбивки, сразу добавляю первый кусок для инициализации и установки duration
  • Видео начинает проигрываться, все отлично
  • Затем, когда в плеере нет новых данных для проигрывания (после события waiting), добавляю новый кусок
  • Видео снова начинает проигрываться, наступает canplay, playing, canplaythrough, timeupdate, timeupdate...
  • Цикл повторяется 3 раза хорошо
  • Когда временная шкала плеера доходит до 10.61 сек., то видео зависает



Видео зависает после добавления очередного куска на 10.61 сек., хотя новые данные в буфере есть(2.5 сек.), но почему то не происходит события canplay после добавления данных. Хром чего-то ожидает, хотя казалось бы есть новые данные - продолжай их играть. Никаких ошибок нет, ни в видео, ни в буфере, ни в MSE

Что мешает хрому проиграть очередной этот кусок не понятно, он просто останавливается и крутится штатное колесико и ожидает данные(?)



Заставить видео вновь начать играть можно двумя способами:
1) video.currentTime = video.currentTime //тупо установить текущую позицию на такую же
2) Подергать вручную временную шкалу, не важно куда чуть взад или вперед
3) Добавить новый кусок

Тогда видео продолжит снова играть, но останавливается уже на 31.9 сек.(уже подольше)

В каких случаях видео не останавливается


  • Если разбивать на меньшее количество кусков, например 5
  • Если добавлять новый кусок сразу после события onupdateend



Не могу понять что за магические метки времени на которых останавливается видео: 10.61 и 31.9 сек.

В Firefox все проигрывается до конца, такой баг только в хромоподобных браузерах(проверял в хроме и опере)

Вот пример кода, там можно заметить на 10 сек. что на шкале есть загруженные данные, но они не проигрываются
https://jsfiddle.net/1w4hyrke/1/

 , , , ,

gobot
()

RSS подписка на новые темы