History

tools: add plotframes script

The script is ported from ffprobe/SourceForge and updated to the current ffprobe version.

Stefano Sabatini committed 13 years ago

Commit c92b6f31 parent 10315b11 file · +164 −0Browse files

Showing the changes to tools/plotframes (1 of 1 file). Show all

Unified · Split

tools/plotframes+164−0
@@ -0,0 +1,164 @@
1+#!/usr/bin/env perl
2+
3+# Copyright (c) 2007-2013 Stefano Sabatini
4+#
5+# This file is part of FFmpeg.
6+#
7+# FFmpeg is free software; you can redistribute it and/or
8+# modify it under the terms of the GNU Lesser General Public
9+# License as published by the Free Software Foundation; either
10+# version 2.1 of the License, or (at your option) any later version.
11+#
12+# FFmpeg is distributed in the hope that it will be useful,
13+# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15+# See the GNU Lesser General Public License for more details.
16+#
17+# You should have received a copy of the GNU Lesser General Public License
18+# along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
19+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
21+=head1 NAME
22+
23+plotframes - Plot video frame sizes using ffprobe and gnuplot
24+
25+=head1 SYNOPSIS
26+
27+plotframes [I<options>] [I<input>]
28+
29+=head1 DESCRIPTION
30+
31+plotframes reads a multimedia files with ffprobe, and plots the
32+collected video sizes with gnuplot.
33+
34+=head1 OPTIONS
35+
36+=over 4
37+
38+=item B<--input|-i> I<infile>
39+
40+Specify multimedia file to read. This is the file passed to the
41+ffprobe command. If not specified it is the first argument passed to
42+the script.
43+
44+=item B<--help|--usage|-h|-?>
45+
46+Print a brief help message and exit.
47+
48+=item B<--manpage|-m>
49+
50+Print the man page.
51+
52+=item B<--output|-o> I<outfile>
53+
54+Set the name of the output used by gnuplot. If not specified no output
55+is created. Must be used in conjunction with the B<terminal> option.
56+
57+=item B<--stream|--s> I<stream_specifier>
58+
59+Specify stream. The value must be a string containing a stream
60+specifier. Default value is "v".
61+
62+=item B<--terminal|-t> I<terminal>
63+
64+Set the name of the terminal used by gnuplot. By default it is
65+"x11". Must be used in conjunction with the B<output> option. Check
66+the gnuplot manual for the valid values.
67+
68+=back
69+
70+=cut
71+
72+=head1 SEE ALSO
73+
74+ffprobe(1), gnuplot(1)
75+
76+=cut
77+
78+use warnings;
79+use strict;
80+
81+use File::Temp;
82+use JSON -support_by_pp;
83+use Getopt::Long;
84+use Pod::Usage;
85+
86+my $input = $ARGV[0];
87+my $stream_specifier = "v";
88+my $gnuplot_terminal = "x11";
89+my $gnuplot_output;
90+
91+GetOptions (
92+ 'input|i=s' => \$input,
93+ 'help|usage|?|h' => sub { pod2usage ( { -verbose => 1, -exitval => 0 }) },
94+ 'manpage|m' => sub { pod2usage ( { -verbose => 2, -exitval => 0 }) },
95+ 'stream|s=s' => \$stream_specifier,
96+ 'terminal|t=s' => \$gnuplot_terminal,
97+ 'output|o=s' => \$gnuplot_output,
98+ ) or pod2usage( { -message=> "Parsing error", -verbose => 1, -exitval => 1 });
99+
100+die "You must specify an input file\n" unless $input;
101+
102+# fetch data
103+my @cmd = (qw{ffprobe -show_entries frame -select_streams}, $stream_specifier, "-of", "json", $input);
104+print STDERR "Executing command: @cmd\n";
105+my $json_struct;
106+{
107+ open(FH, "-|", @cmd) or die "ffprobe command failed: $!\n";
108+ local $/;
109+ my $json_text = <FH>;
110+ close FH;
111+ die "ffprobe command failed" if $?;
112+ eval { $json_struct = decode_json($json_text); };
113+ die "JSON parsing error: $@\n" if $@;
114+}
115+
116+# collect and print frame statistics per pict_type
117+my %stats;
118+my $frames = $json_struct->{frames};
119+my $frame_count = 0;
120+foreach my $frame (@{$frames}) {
121+ my $type = $frame->{pict_type};
122+ $frame->{count} = $frame_count++;
123+ if (not $stats{$type}) {
124+ $stats{$type}->{tmpfile} = File::Temp->new(SUFFIX => '.dat');
125+ my $fn = $stats{$type}->{tmpfile}->filename;
126+ open($stats{$type}->{fh}, ">", $fn) or die "Can't open $fn";
127+ }
128+
129+ print { $stats{$type}->{fh} }
130+ "$frame->{count} ", $frame->{pkt_size} * 8 / 1000, "\n";
131+}
132+foreach (keys %stats) { close $stats{$_}->{fh}; }
133+
134+# write gnuplot script
135+my %type_color_map = (
136+ "I" => "red",
137+ "P" => "green",
138+ "B" => "blue"
139+ );
140+
141+my $gnuplot_script_tmpfile = File::Temp->new(SUFFIX => '.gnuplot');
142+my $fn = $gnuplot_script_tmpfile->filename;
143+open(FH, ">", $fn) or die "Couldn't open $fn: $!";
144+print FH << "EOF";
145+set title "video frame sizes"
146+set xlabel "frame time"
147+set ylabel "frame size (Kbits)"
148+set grid
149+set terminal "$gnuplot_terminal"
150+EOF
151+
152+print FH "set output \"$gnuplot_output\"\n" if $gnuplot_output;
153+print FH "plot";
154+my $sep = "";
155+foreach my $type (keys %stats) {
156+ my $fn = $stats{$type}->{tmpfile}->filename;
157+ print FH "$sep\"$fn\" title \"$type frames\" with impulses";
158+ print FH " linecolor rgb \"$type_color_map{$type}\"" if $type_color_map{$type};
159+ $sep = ", ";
160+}
161+close FH;
162+
163+# launch gnuplot with the generated script
164+system ("gnuplot", "--persist", $gnuplot_script_tmpfile->filename);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t