| 1 |
#!/usr/bin/perl |
| 2 |
|
| 3 |
use Video::Capture::V4l; |
| 4 |
use Video::RTjpeg; |
| 5 |
|
| 6 |
$|=1; |
| 7 |
$SIG{PIPE} = 'IGNORE'; |
| 8 |
|
| 9 |
$stream = "/tmp/vstream"; |
| 10 |
require $stream; |
| 11 |
|
| 12 |
$mpegencode = "/root/cvt/mpeg_movie-1.6.0/video_in/mpeg_encode"; |
| 13 |
|
| 14 |
my $gop = 8; |
| 15 |
|
| 16 |
$tmpdir = "/tmp/encode$$/"; |
| 17 |
$tmpdir = "/tmp/encode"; |
| 18 |
mkdir $tmpdir, 0700; |
| 19 |
|
| 20 |
$fsize = $w*$h*2; |
| 21 |
|
| 22 |
$partlen = $fps*60; |
| 23 |
$partlen = $gop*100; |
| 24 |
|
| 25 |
my @dec; |
| 26 |
|
| 27 |
sub new_vdecoder { |
| 28 |
my $number = @dec; |
| 29 |
my $decp = do { local *DECODER_READER }; |
| 30 |
my $decc = do { local *DECODER_WRITER }; |
| 31 |
pipe $decp, $decc; |
| 32 |
if (fork==0) { |
| 33 |
my ($buf, $tables); |
| 34 |
open DATA, "<$outprefix.v$number" or die; |
| 35 |
|
| 36 |
read DATA, $buf, 4; |
| 37 |
my ($tlen) = unpack "N*", $buf; |
| 38 |
|
| 39 |
read DATA, $tables, $tlen; |
| 40 |
Video::RTjpeg::init_decompress($tables, $w, $h); |
| 41 |
|
| 42 |
while (read DATA, $buf, 8) { |
| 43 |
my ($time, $size) = unpack "N*", $buf; |
| 44 |
print $decc pack "N", $time; |
| 45 |
read DATA, $buf, $size; |
| 46 |
print $decc Video::RTjpeg::decompress $buf; |
| 47 |
} |
| 48 |
exit; |
| 49 |
} |
| 50 |
push @dec, $decp; |
| 51 |
} |
| 52 |
|
| 53 |
my @nframeid; |
| 54 |
|
| 55 |
sub next_frame { |
| 56 |
my $min = 1e30; |
| 57 |
my $buf; |
| 58 |
my $minid; |
| 59 |
for (0..$#dec) { |
| 60 |
unless (defined $nframeid[$_]) { |
| 61 |
read $dec[$_], $buf, 4; |
| 62 |
$nframeid[$_] = unpack "N", $buf; |
| 63 |
} |
| 64 |
($min,$minid) = ($nframeid[$_],$_) if $nframeid[$_] < $min && defined $nframeid[$_]; |
| 65 |
} |
| 66 |
read $dec[$minid], $buf, $fsize; |
| 67 |
undef $nframeid[$minid]; |
| 68 |
($buf, $min); |
| 69 |
} |
| 70 |
|
| 71 |
new_vdecoder for 1..$vencoders; |
| 72 |
|
| 73 |
my $part = 0; |
| 74 |
|
| 75 |
sub do_encode { |
| 76 |
my ($pstart, $pframes) = @_; |
| 77 |
$pframes = sprintf "%06d", $pframes-1; |
| 78 |
$part = sprintf "%03d", $part+1; |
| 79 |
|
| 80 |
open TEMPLATE, ">$tmpdir/param" or die; |
| 81 |
print TEMPLATE <<EOF; |
| 82 |
OUTPUT $outprefix.$part.mpg |
| 83 |
|
| 84 |
#PATTERN IBBBPBBB |
| 85 |
PATTERN IBBBPBBBPBBBPBBBPBBBPBBBPBBBPBBB |
| 86 |
FORCE_ENCODE_LAST_FRAME |
| 87 |
|
| 88 |
# You must specify the type of the input files. The choices are: |
| 89 |
# YUV, PPM, JMOVIE, Y, JPEG, PNM |
| 90 |
# |
| 91 |
BASE_FILE_FORMAT YUV |
| 92 |
|
| 93 |
# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running |
| 94 |
YUV_SIZE ${w}x$h |
| 95 |
|
| 96 |
# EYUV or UCB are the same as previous versions of this encoder. |
| 97 |
# (All the Y's, then U's then V's, in 4:2:0 subsampling.) |
| 98 |
# Other formats, such as Abekas, Phillips, or a general format are |
| 99 |
# permissible, the general format is a string of Y's, U's, and V's |
| 100 |
# to specify the file order. |
| 101 |
|
| 102 |
INPUT_FORMAT EYUV |
| 103 |
|
| 104 |
INPUT_CONVERT * |
| 105 |
|
| 106 |
# number of frames in a GOP. |
| 107 |
# |
| 108 |
# since each GOP must have at least one I-frame, the encoder will find the |
| 109 |
# the first I-frame after GOP_SIZE frames to start the next GOP |
| 110 |
# |
| 111 |
# later, will add more flexible GOP signalling |
| 112 |
# |
| 113 |
GOP_SIZE $partlen |
| 114 |
|
| 115 |
# number of slices in a frame |
| 116 |
# |
| 117 |
# 1 is a good number. another possibility is the number of macroblock rows |
| 118 |
# (which is the height divided by 16) |
| 119 |
# |
| 120 |
SLICES_PER_FRAME $w |
| 121 |
|
| 122 |
# directory to get all input files from (makes this file easier to read) |
| 123 |
INPUT_DIR $tmpdir |
| 124 |
|
| 125 |
# There are a bunch of ways to specify the input files. |
| 126 |
# from a simple one-per-line listing, to the following |
| 127 |
# way of numbering them. See the manual for more information. |
| 128 |
INPUT |
| 129 |
# '*' is replaced by the numbers 01, 02, 03, 04 |
| 130 |
# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11 |
| 131 |
# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11 |
| 132 |
# if I instead do [1-11+3], it would be 1, 4, 7, 10 |
| 133 |
# the program assumes none of your input files has a name ending in ']' |
| 134 |
# if you do, too bad!!! |
| 135 |
# |
| 136 |
# |
| 137 |
frame*.yuv [000000-$pframes] |
| 138 |
END_INPUT |
| 139 |
|
| 140 |
# Many of the remaining options have to do with the motion search and qscale |
| 141 |
|
| 142 |
# FULL or HALF -- must be upper case |
| 143 |
PIXEL HALF |
| 144 |
|
| 145 |
# means +/- this many pixels for both P and B frame searches |
| 146 |
# specify two numbers if you wish to serc different ranges in the two. |
| 147 |
RANGE 10 |
| 148 |
|
| 149 |
# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC} |
| 150 |
PSEARCH_ALG LOGARITHMIC |
| 151 |
|
| 152 |
# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE} |
| 153 |
# |
| 154 |
# note that EXHAUSTIVE is really, really, really slow |
| 155 |
# |
| 156 |
BSEARCH_ALG CROSS2 |
| 157 |
|
| 158 |
# |
| 159 |
# these specify the q-scale for I, P, and B frames |
| 160 |
# (values must be between 1 and 31) |
| 161 |
# These are the Qscale values for the entire frame in variable bit-rate |
| 162 |
# mode, and starting points (but not important) for constant bit rate |
| 163 |
# |
| 164 |
IQSCALE 8 |
| 165 |
PQSCALE 10 |
| 166 |
BQSCALE 25 |
| 167 |
|
| 168 |
# this must be ORIGINAL or DECODED |
| 169 |
REFERENCE_FRAME DECODED |
| 170 |
|
| 171 |
# for parallel parameters see parallel.param in the exmaples subdirectory |
| 172 |
|
| 173 |
# if you want constant bit-rate mode, specify it as follows (number is bits/sec): |
| 174 |
#BIT_RATE 2000000 |
| 175 |
|
| 176 |
# To specify the buffer size (327680 is default, measused in bits, for 16bit words) |
| 177 |
#BUFFER_SIZE 800000 |
| 178 |
|
| 179 |
# The frame rate is the number of frames/second (legal values: |
| 180 |
# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60 |
| 181 |
FRAME_RATE $fps |
| 182 |
|
| 183 |
# There are many more options, see the users manual for examples.... |
| 184 |
# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc. |
| 185 |
|
| 186 |
#PARALLEL_TEST_FRAMES 3 |
| 187 |
#PARALLEL_CHUNK_TAPER |
| 188 |
|
| 189 |
#PARALLEL |
| 190 |
#localhost1 root $mpegencode |
| 191 |
#localhost2 root $mpegencode |
| 192 |
#END_PARALLEL |
| 193 |
|
| 194 |
EOF |
| 195 |
|
| 196 |
close TEMPLATE; |
| 197 |
|
| 198 |
$ENV{HOST} = "localhost"; |
| 199 |
system $mpegencode, "-quiet", "10", "$tmpdir/param"; |
| 200 |
} |
| 201 |
|
| 202 |
my ($frame, $pstart, $pframe) = (0, 0, 0); |
| 203 |
|
| 204 |
Video::RTjpeg::init_decompress("x" x (128*4), $w, $h); |
| 205 |
while (my ($buf, $framex) = next_frame) { |
| 206 |
print "."; |
| 207 |
while ($frame < $framex) { |
| 208 |
if ($pframe == $partlen) { |
| 209 |
do_encode $pstart, $pframe; |
| 210 |
$pstart = $frame; |
| 211 |
$pframe = 0; |
| 212 |
} |
| 213 |
#$buf2 = Video::RTjpeg::yuvrgb($buf); open DISPLAY, "| display -size ${w}x$h rgb:-" or die; print DISPLAY $buf2; close DISPLAY; |
| 214 |
open FRAME, sprintf ">$tmpdir/frame%06d.yuv", $pframe; |
| 215 |
print FRAME $buf; |
| 216 |
close FRAME; |
| 217 |
$frame++; |
| 218 |
$pframe++; |
| 219 |
print "s" if $frame != $framex; |
| 220 |
} |
| 221 |
last if $frame >= $nframe; |
| 222 |
} |
| 223 |
|
| 224 |
do_encode $pstart, $pframe; |
| 225 |
|