Пропустить N байтов каждые M байтов при чтении из именованного канала

393
peetonn

Я передаю данные из одного процесса в другой, но этот поток необходимо отфильтровать. Первый процесс есть, ffmpegа второй есть ffplay. ffmpegпредоставляет необработанный видеокадр для fplayрендеринга, однако он добавляет заголовок 32 байта к каждому кадру . Для кадра 720p это означает, что каждые 1280x720x4 байта дополнены 32 байтами.

Это влияет на ffplayвоспроизведение, и мне нужно иметь некоторую фильтрацию этого потока байтов, которая будет отбрасывать этот заголовок для каждого кадра. Скорее всего, такие инструменты, как odили xxdдолжны быть использованы, но мне трудно понять, как именно.

0

1 ответ на вопрос

0
choroba

Perl на помощь!

perl -e 'print substr $buff, 32 while sysread *STDIN, $buff, 1280 * 720 * 4 + 32' 

Смотрите substr и sysread .

Может возникнуть проблема, если SSIZE_MAX на вашей платформе меньше 1280 * 720 * 4 + 32 или по какой-то другой причине вы не можете прочитать все байты одновременно. Может быть, попробуйте этот скрипт на Perl:

#!/usr/bin/perl use warnings; use strict;  my ($BLOCK_SIZE, $HEADER_SIZE) = (3686400, 32);  while (1) { my $block_size = 0; my $block = ""; my $buff_size; while (1) { $buff_size = sysread *STDIN, my $buff, $HEADER_SIZE + $BLOCK_SIZE - $block_size; last unless $buff_size;  $block .= $buff; $block_size += $buff_size; } last unless $block_size;  substr $block, 0, $HEADER_SIZE, ""; print $block; } 
Спасибо за ответ! Я попробовал, но по какой-то причине он вырезает больше байтов, чем указано. Например, когда я сохраняю 1 кадр видео в файл после вычитания 1 байта, фактически в результирующем файле отсутствуют 57 байтов: `ffmpeg -f avfoundation -pixel_format 0rgb -framerate 25 -video_size 1280x720 -i" 0 "-map 0: v -c copy -f rawvideo -vframes 1 - | perl -e 'print substr $ buff, 1, а sysread * STDIN, $ buff, 3686432'> / tmp / frame.0rgb`. Подсчет байтов `wc -c / tmp.frame.0rgb` peetonn 5 лет назад 0
Я попробовал это с `echo | sed 's / // g'` и он корректно выводит `cdefgjklmnqrstuxyz` для 5 + 2. Проверьте свои числа. choroba 5 лет назад 0
Можете ли вы попробовать это: `dd if = / dev / urandom bs = 3686432 count = 1> / tmp / random`, что дает 3686432 случайных байта (` wc -c / tmp / random`), а затем `cat / tmp / random | perl -e 'print substr $ buff, 32 while sysread * STDIN, $ buff, 3686432'> / tmp / truncated` - ожидается, что даст 3686400, но это не так - вместо этого выдает 3684256 байт (`wc -c / tmp / truncated) `). peetonn 5 лет назад 0
@peeton: это работает для меня. Какая версия Perl у вас есть? choroba 5 лет назад 0
странно: `Это Perl 5, версия 18, Subversion 2 (v5.18.2), созданная для darwin-thread-multi-2level (с 2 зарегистрированными патчами, смотрите perl -V для более подробной информации)` peetonn 5 лет назад 0
Я на v5.18.2 построен для x86_64-linux-thread-multi: -o choroba 5 лет назад 0
Также разница составляет 2 ^ 5 * 67. choroba 5 лет назад 0
Может быть проблема с SSIZE_MAX? choroba 5 лет назад 0
@peetonn: Пожалуйста, попробуйте более сложный скрипт. choroba 5 лет назад 0

Похожие вопросы