Überspringen Sie N Bytes alle M Bytes, während Sie aus Named Pipe lesen

485
peetonn

Ich leite Daten von einem Prozess zum anderen, aber dieser Stream muss gefiltert werden. Der erste Prozess ist ffmpegund der zweite ist ffplay. ffmpegBietet einen unaufbereiteten Video-Frame fplayzum Rendern, fügt jedoch jedem Frame 32 Byte Header hinzu . Bei einem 720p-Frame bedeutet dies, dass jedem 1280x720x4-Byte 32 Byte vorangestellt werden.

Dies wirkt sich auf die ffplayWiedergabe aus und ich muss etwas Filterung dieses Byte-Streams durchführen, der diesen Header für jeden Frame löschen wird. Am ehesten sollten Werkzeuge wie ododer xxdverwendet werden, aber ich habe Schwierigkeiten, herauszufinden, wie genau.

0

1 Antwort auf die Frage

0
choroba

Perl zur Rettung!

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

Siehe substr und sysread .

Es kann ein Problem auftreten, wenn SSIZE_MAX auf Ihrer Plattform weniger als 1280 * 720 * 4 + 32 beträgt oder Sie aus einem anderen Grund nicht alle Bytes gleichzeitig lesen können. Versuchen Sie es stattdessen mit diesem Perl-Skript:

#!/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; } 
Danke für die Antwort! Ich habe es versucht, aber aus irgendeinem Grund schneidet es mehr Bytes aus als angegeben. Wenn ich zum Beispiel 1 Frame eines Videos in eine Datei speichere, nachdem ich 1 Byte subtrahiert habe, fehlen tatsächlich 57 Bytes: `ffmpeg -f avfoundation -pixel_format 0rgb -framerate 25 -video_size 1280x720 -i" 0 "-map 0: v -c kopieren -f rawvideo -vframes 1 - | perl -e 'druck substr $ buff, 1 während sysread * STDIN, $ buff, 3686432'> / tmp / frame.0rgb`. Zählen Sie die Bytes `wc -c / tmp.frame.0rgb` peetonn vor 6 Jahren 0
Ich habe es mit `echo | versucht sed 's / // g' 'und es gibt' cdefgjklmnqrstuxyz 'für 5 + 2 korrekt aus. Überprüfen Sie Ihre Zahlen. choroba vor 6 Jahren 0
Kannst du folgendes versuchen: `dd if = / dev / urandom bs = 3686432 count = 1> / tmp / random`, was 3686432 zufällige Bytes (` wc -c / tmp / random`) und dann `cat / tmp / random | ergibt perl -e 'print substr $ buff, 32 während sysread * STDIN, $ buff, 3686432'> / tmp / truncated` - voraussichtlich 3686400, aber nicht - gibt stattdessen 3684256 Bytes (`wc -c / tmp / truncated `). peetonn vor 6 Jahren 0
@peeton: Es funktioniert für mich. Welche Perl-Version hast du? choroba vor 6 Jahren 0
seltsam: `Dies ist Perl 5, Version 18, Subversion 2 (v5.18.2), das für Darwin-Thread-Multi-2-Level (mit 2 registrierten Patches, siehe ausführlicher unter Perl -V) erstellt wurde peetonn vor 6 Jahren 0
Ich bin auf v5.18.2 für x86_64-linux-thread-multi gebaut: -o choroba vor 6 Jahren 0
Der Unterschied ist auch 2 ^ 5 * 67. choroba vor 6 Jahren 0
Vielleicht ein Problem mit SSIZE_MAX? choroba vor 6 Jahren 0
@peetonn: Bitte versuche es mit dem komplexeren Skript. choroba vor 6 Jahren 0