File: mpgenc

package info (click to toggle)
libvideo-capture-v4l-perl 0.224-5
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 572 kB
  • ctags: 563
  • sloc: ansic: 4,924; perl: 2,746; makefile: 57; sh: 22
file content (225 lines) | stat: -rwxr-xr-x 5,633 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/perl

use Video::Capture::V4l;
use Video::RTjpeg;

$|=1;
$SIG{PIPE} = 'IGNORE';

$stream = "/tmp/vstream";
require $stream;

$mpegencode = "/root/cvt/mpeg_movie-1.6.0/video_in/mpeg_encode";

my $gop = 8;

$tmpdir = "/tmp/encode$$/";
$tmpdir = "/tmp/encode";
mkdir $tmpdir, 0700;

$fsize  = $w*$h*2;

$partlen = $fps*60;
$partlen = $gop*100;

my @dec;

sub new_vdecoder {
   my $number = @dec;
   my $decp = do { local *DECODER_READER };
   my $decc = do { local *DECODER_WRITER };
   pipe $decp, $decc;
   if (fork==0) {
      my ($buf, $tables);
      open DATA, "<$outprefix.v$number" or die;

      read DATA, $buf, 4;
      my ($tlen) = unpack "N*", $buf;

      read DATA, $tables, $tlen;
      Video::RTjpeg::init_decompress($tables, $w, $h);

      while (read DATA, $buf, 8) {
         my ($time, $size) = unpack "N*", $buf;
         print $decc pack "N", $time;
         read DATA, $buf, $size;
         print $decc Video::RTjpeg::decompress $buf;
      }
      exit;
   }
   push @dec, $decp;
}

my @nframeid;

sub next_frame {
   my $min = 1e30;
   my $buf;
   my $minid;
   for (0..$#dec) {
      unless (defined $nframeid[$_]) {
         read $dec[$_], $buf, 4;
         $nframeid[$_] = unpack "N", $buf;
      }
      ($min,$minid) = ($nframeid[$_],$_) if $nframeid[$_] < $min && defined $nframeid[$_];
   }
   read $dec[$minid], $buf, $fsize;
   undef $nframeid[$minid];
   ($buf, $min);
}

new_vdecoder for 1..$vencoders;

my $part = 0;

sub do_encode {
   my ($pstart, $pframes) = @_;
   $pframes = sprintf "%06d", $pframes-1;
   $part = sprintf "%03d",  $part+1;

   open TEMPLATE, ">$tmpdir/param" or die;
   print TEMPLATE <<EOF;
OUTPUT		$outprefix.$part.mpg

#PATTERN		IBBBPBBB
PATTERN		IBBBPBBBPBBBPBBBPBBBPBBBPBBBPBBB
FORCE_ENCODE_LAST_FRAME

# You must specify the type of the input files.  The choices are:
#    YUV, PPM, JMOVIE, Y, JPEG, PNM
#
BASE_FILE_FORMAT	YUV

# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running
YUV_SIZE	${w}x$h

# EYUV or UCB are the same as previous versions of this encoder.
# (All the Y's, then U's then V's, in 4:2:0 subsampling.)
# Other formats, such as Abekas, Phillips, or a general format are
# permissible, the general format is a string of Y's, U's, and V's
# to specify the file order.

INPUT_FORMAT EYUV

INPUT_CONVERT	*

# number of frames in a GOP.
#
# since each GOP must have at least one I-frame, the encoder will find the
# the first I-frame after GOP_SIZE frames to start the next GOP
#
# later, will add more flexible GOP signalling
#
GOP_SIZE	$partlen

# number of slices in a frame
#
# 1 is a good number.  another possibility is the number of macroblock rows
# (which is the height divided by 16)
#
SLICES_PER_FRAME	$w

# directory to get all input files from (makes this file easier to read)
INPUT_DIR	$tmpdir

# There are a bunch of ways to specify the input files.
# from a simple one-per-line listing, to the following 
# way of numbering them.  See the manual for more information.
INPUT
# '*' is replaced by the numbers 01, 02, 03, 04
# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11
# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11
# if I instead do [1-11+3], it would be 1, 4, 7, 10
# the program assumes none of your input files has a name ending in ']'
# if you do, too bad!!!
#
#
frame*.yuv	[000000-$pframes]
END_INPUT

# Many of the remaining options have to do with the motion search and qscale

# FULL or HALF -- must be upper case
PIXEL		HALF

# means +/- this many pixels for both P and B frame searches
# specify two numbers if you wish to serc different ranges in the two.
RANGE		10

# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}
PSEARCH_ALG	LOGARITHMIC

# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}
#
# note that EXHAUSTIVE is really, really, really slow
#
BSEARCH_ALG	CROSS2

#
# these specify the q-scale for I, P, and B frames
# (values must be between 1 and 31)
# These are the Qscale values for the entire frame in variable bit-rate
# mode, and starting points (but not important) for constant bit rate
#
IQSCALE		8
PQSCALE		10
BQSCALE		25

# this must be ORIGINAL or DECODED
REFERENCE_FRAME	DECODED

# for parallel parameters see parallel.param in the exmaples subdirectory

# if you want constant bit-rate mode, specify it as follows (number is bits/sec):
#BIT_RATE  2000000

# To specify the buffer size (327680 is default, measused in bits, for 16bit words)
#BUFFER_SIZE 800000

# The frame rate is the number of frames/second (legal values:
# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
FRAME_RATE $fps

# There are many more options, see the users manual for examples....
# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.

#PARALLEL_TEST_FRAMES	3
#PARALLEL_CHUNK_TAPER

#PARALLEL
#localhost1	root	$mpegencode
#localhost2	root	$mpegencode
#END_PARALLEL

EOF

   close TEMPLATE;

   $ENV{HOST} = "localhost";
   system $mpegencode, "-quiet", "10", "$tmpdir/param";
}

my ($frame, $pstart, $pframe) = (0, 0, 0);

Video::RTjpeg::init_decompress("x" x (128*4), $w, $h);
while (my ($buf, $framex) = next_frame) {
   print ".";
   while ($frame < $framex) {
      if ($pframe == $partlen) {
         do_encode $pstart, $pframe;
         $pstart = $frame;
         $pframe = 0;
      }
      #$buf2 = Video::RTjpeg::yuvrgb($buf); open DISPLAY, "| display -size ${w}x$h rgb:-" or die; print DISPLAY $buf2; close DISPLAY;
      open FRAME, sprintf ">$tmpdir/frame%06d.yuv", $pframe;
      print FRAME $buf;
      close FRAME;
      $frame++;
      $pframe++;
      print "s" if $frame != $framex;
   }
   last if $frame >= $nframe;
}

do_encode $pstart, $pframe;