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

0

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

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

peetonn
источник

Ответы:

0

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;
}
choroba
источник
Спасибо за ответ! Я пробовал, но по какой-то причине он вырезает больше байтов, чем указано. Например, когда я сохраняю 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 while sysread *STDIN, $buff, 3686432' > /tmp/frame.0rgb. Подсчет байтовwc -c /tmp.frame.0rgb
peetonn
Я попробовал это с, echo {a..z} | sed 's/ //g'и это правильно выводит cdefgjklmnqrstuxyzдля 5 + 2. Проверьте свои числа.
Чороба
Можете ли вы попробовать это: 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).
августа
@peeton: это работает для меня. Какая версия Perl у вас есть?
Чороба
странно:This is perl 5, version 18, subversion 2 (v5.18.2) built for darwin-thread-multi-2level (with 2 registered patches, see perl -V for more detail)
peetonn