Прямой эфир

0
Видел я эту шпаргалку, но на мои вопросы она не ответила. Пришлось ковырять какие-то сырки, более полные.
  • avatar
  • Vga
  • 13 ноября 2019, 14:54
0
Положил сюда
0
ссилка на библиотеку умерла, скиньте пожалуйста библиотеку
0
Другим могло бы быть описание формата MP4, если бы оно, гм, было.
Не-не-не, я пока не ошалел форматы ISO описывать. Могу подсказать неплохую шпаргалку от Simarron Systems.
  • avatar
  • anakost
  • 12 ноября 2019, 19:19
0
А, статье уже есть такое, и несколько правильней написанное.
  • avatar
  • Vga
  • 12 ноября 2019, 06:42
0
function SwapEndian64(Value: Int64): Int64; register;
asm
  mov eax, [ebp+$0c]
  mov edx, [ebp+$08]
  bswap eax
  bswap edx
end;
  • avatar
  • Vga
  • 12 ноября 2019, 06:35
0
Интересно, что там нагенерилось в ассемблере.
Ухх, какая жесть. Чего стоит одно копирование данных из стека в EDX:EAX и затем
XOR EAX, EAX ; и зачем было грузить?
MOV EAX, EDX ; и зачем было очищать?
XOR EDX, EDX
  • avatar
  • Vga
  • 12 ноября 2019, 05:57
0
При 32-битном аргументе это бесполезно.
Это сокращает исходный код, выкидывая из него лишнюю семантическую единицу. При таком влиянии оптимальности свопа как в этом случае такое изменение оправдано даже если оно замедляет код.
Время исполнения 12.765 ms. Но т.к. функции изменения эндианности узким местом не являются и их убыстрение сравнимо со статистической погрешностью, не думаю что стоит этим заниматься.
Хотя они не являются узким местом кода, они являются единственным интересным местом статьи. Другим могло бы быть описание формата MP4, если бы оно, гм, было.
  • avatar
  • Vga
  • 12 ноября 2019, 05:32
0
И я бы выкинул Result := Value, написав в следующей строке Result := ((Value and $FF00) shr 8) or ((Value and $00FF) shl 8). Выхлоп врядли изменится, но зачем захламлять код лишними операциями?
При 32-битном аргументе это бесполезно. У функции не указан спецификатор передачи параметров, значит это register. При этом спецификаторе 32-битный аргумент передается в EAX, и 32-битный результат читается из EAX. Поэтому в функции
function Func(Value: DWord): DWord;
begin
Result := Value;
end;
при записи на ассемблере не нужно ни строчки кода. Другое дело если аргумент 64-битный, т.е. превышает разрядность компилятора. При этом в EAX будет не сам аргумент, а ссылка на него. Это наводит на мысль что функцию SwapEndian64 нужно записать по другому:
function SwapEndian64e(Value: Int64): Int64;
begin
Result := ((Value and $FFFFFFFF00000000) shr 32) or ((Value and $00000000FFFFFFFF) shl 32);
Result := ((Result and $FFFF0000FFFF0000) shr 16) or ((Result and $0000FFFF0000FFFF) shl 16);
Result := ((Result and $FF00FF00FF00FF00) shr 8) or ((Result and $00FF00FF00FF00FF) shl 8);
end;
Время исполнения действительно уменьшается и функция начинает обгонять метод прямого обмена байтами — 24.685 ms. Но все-же довольно медленно, наверное 64-битный аргумент обрабатывается по половине 32-битным компилятором. Посмотрев ассемблерный листинг это ясно видно.
Эффективнее сделать это самому, обработать 32-битные половинки отдельно и обменять. Дополнил статью.
Еще чуть выиграть можно, подставив свопы прямо в тело функции, а не вызывая Swap32.
Если-бы функции изменения эндианности были узким местом в алгоритме, можно было-бы пойти дальше и убрать вызовы функций, разместив их непосредственно в коде.
function SwapEndian64e(Value: Int64): Int64;
type
  Long64Rec = packed record
    case Integer of
      0: (Lo, Hi: DWord);
      1: (Bytes: array [0..7] of Byte);
  end;
var
  InBuff: Long64Rec absolute Value;
  OutBuff: Long64Rec absolute Result;
begin
  OutBuff.Lo := ((InBuff.Hi and $FFFF0000) shr 16) or ((InBuff.Hi and $0000FFFF) shl 16);
  OutBuff.Lo := ((OutBuff.Lo and $FF00FF00) shr 8) or ((OutBuff.Lo and $00FF00FF) shl 8);
  OutBuff.Hi := ((InBuff.Lo and $FFFF0000) shr 16) or ((InBuff.Lo and $0000FFFF) shl 16);
  OutBuff.Hi := ((OutBuff.Hi and $FF00FF00) shr 8) or ((OutBuff.Hi and $00FF00FF) shl 8);
end;

Время исполнения 12.765 ms. Но т.к. функции изменения эндианности узким местом не являются и их убыстрение сравнимо со статистической погрешностью, не думаю что стоит этим заниматься.
  • avatar
  • anakost
  • 11 ноября 2019, 18:59
0
Без комментария алгоритм сразу не понять:
Стандартные решения вроде этого должны опознаваться с первого взгляда. И я бы выкинул Result := Value, написав в следующей строке Result := ((Value and $FF00) shr 8) or ((Value and $00FF) shl 8). Выхлоп врядли изменится, но зачем захламлять код лишними операциями?
и ненамного уступает ассемблерным.
Примерно на 35% дольше. При частом использовании может быть существенно.
Вот и неожиданность, метод на паскале через сдвиг и замену по маске оказался медленнее прямого обмена регистрами для 64-разрядного аргумента.
Похоже, 64-битные сдвиги в 32-битном коде жутко медленны. Интересно, что там нагенерилось в ассемблере.
Были отобраны по две самые быстрые функции, на ассемблере и на паскале
А с чего это на паскале самая быстрая — с обменом по байтикам? Я думаю, перестановка двух свопнутых сдвигами двордов будет быстрее, причем в два раза. Еще чуть выиграть можно, подставив свопы прямо в тело функции, а не вызывая Swap32.
Получение разрешения этих двух файлов запускалось в цикле на 5000 итераций.
А вот здесь итерировать как раз не надо. Винда умная и пять тысяч раз читать файл не будет. А на практике уже ты не будешь по 5к раз подряд один файл читать. Возьми папку с кучей нормальных файлов, суммарным размером в несколько гигабайт и запроси у каждого по разу. Причем между тестами (и перед тестами, если ты эту папку собирал прямо перед тестом) TFileStream и TMemoryStream надо выбить буферизацию файлов из памяти — скажем, скопировать с диска на диск файлов на 2-3 объема установленной RAM.
  • avatar
  • Vga
  • 11 ноября 2019, 03:13
0
Код был написан для имеющихся в наличии файлов и работает быстро и безошибочно. Улыбнуло, ваш комментарий
Будет вам ещё с чем покопаться, когда зальют файл с 64-битными боксами.
напоминает анекдот о суровых таежных лесорубах и японской бензопиле.
  • avatar
  • anakost
  • 09 ноября 2019, 05:44
0
Дополнил оптимизацией.
  • avatar
  • anakost
  • 08 ноября 2019, 18:01
0
А ffprobe с выводом в json или xml — будет таки приятнее обрабатывать, нежели сырые боксы из mp4. Будет вам ещё с чем покопаться, когда зальют файл с 64-битными боксами.
  • avatar
  • tipok
  • 07 ноября 2019, 21:52
0
Можно на прямую в USB. LIBUSB прикручивается.
  • avatar
  • __bl__
  • 03 ноября 2019, 16:21
0
Ну-у, если говорить о читабельности, тот тут еще много к чему можно придраться. На этом фоне функции конвертирования эндианности — явно не проблема. Да и оно хоть и на ассемблере, а на редкость прямолинейно и понятно. Проблемы будут разве что если тащить этот код в десятую студию и собирать под какой-нить айфон.
еще лучше воспользоваться WinAPI с функциями CreateFile и CreateFileMapping.
TFileStream внутри — тот же CreateFile, а маппинг… Вряд ли он что-то даст кроме усложнения кода.
  • avatar
  • Vga
  • 03 ноября 2019, 00:56
0
Ко скоро должны доставить контроллер от NI USB посмотрю что у него внутри. Дальше буду на нем практиковаться.
  • avatar
  • gadz
  • 02 ноября 2019, 22:02
0
Класс TMemoryStream применен на этапе изучения воэможности определения разрешения видеофайла формата MP4 прямым парсингом. Представленный код это только подтверждение такой возможности. Тонкости реализации и загрузка памяти на этом этапе меня не очень волновали. А так да, с точки зрения рационального использования памяти применение TFileStream лучше, еще лучше воспользоваться WinAPI с функциями CreateFile и CreateFileMapping.
Не думаю, что перевод функций конвертирования эндианности в ассемблерный вид даст какой-то значимый эффект. И даже если я выиграю тысячную долю секунды, зачем мне это? Выигрыш мизерный, читабельность гораздо хуже.
  • avatar
  • anakost
  • 02 ноября 2019, 21:32
0
Просто тогда лабьвю тут не к месту оказывалась бы. Она то думает, что это ком порт. Интересно, а через усб напрямую ее как можно заставить работать. Скажем через VCP или может быть HID профиль.
  • avatar
  • DIHALT
  • 02 ноября 2019, 21:16
0
Я подумал раз к компьютеру соединяется USB кабель. Формально никто не видит ком порт.
  • avatar
  • gadz
  • 02 ноября 2019, 20:08
0
Ну так тут не USB, а ком порт. УСБой тут фтди занимается.
  • avatar
  • DIHALT
  • 02 ноября 2019, 20:04