1 | #!/bin/bash |
---|
2 | # |
---|
3 | # This shell script generates a parameter file suitable for use |
---|
4 | # with mpeg2encode from http://www.mpeg.org/MSSG/. |
---|
5 | # |
---|
6 | # make_mpeg2encode_parfile is part of a group of unix shell scripts to aid in converting a group |
---|
7 | # of still-frame images to an mpeg-1 animation. |
---|
8 | # More information can be found at http://marc.me.utexas.edu/mpeg_tools.html. |
---|
9 | # |
---|
10 | # |
---|
11 | # There is no error checking. It is basic but functional. |
---|
12 | # It relies upon: |
---|
13 | # /bin/sh |
---|
14 | # awk |
---|
15 | # identify (from ImageMagick, http://www.imagemagick.org) |
---|
16 | # |
---|
17 | # Usage: |
---|
18 | # make_mpeg2encode_parfile filelist |
---|
19 | # |
---|
20 | # where required arguemnts are: |
---|
21 | # |
---|
22 | # filelist - filenames, including directory, where the still frame images reside |
---|
23 | # |
---|
24 | # |
---|
25 | # Examples: |
---|
26 | # make_mpeg2encode_parfile /tmp/images/* |
---|
27 | # make_mpeg2encode_parfile /tmp/images/scenarioA*.tif |
---|
28 | # |
---|
29 | # where the /tmp/images directory contains files something like: |
---|
30 | # |
---|
31 | # frame.00001.tif |
---|
32 | # frame.00002.tif |
---|
33 | # frame.00003.tif |
---|
34 | # ... |
---|
35 | # frame.00486.tif |
---|
36 | # |
---|
37 | # The individual frames do not have to be tiff's; they can be any format 'convert' handles. |
---|
38 | # See notes within the 'imagetoppm' or 'imagetoyuv' scripts at |
---|
39 | # http://marc.me.utexas.edu/mpeg_tools.html. |
---|
40 | # |
---|
41 | # Result: mpeg2encode.par left in current working directory |
---|
42 | # |
---|
43 | # |
---|
44 | # Next possible steps to make a movie: |
---|
45 | # (1) ensure the images are converted from whatever format into either ppm or yuv with: |
---|
46 | # imagetoppm ./images/*.tif |
---|
47 | # or |
---|
48 | # imagetoyuv ./images/*.gif |
---|
49 | # |
---|
50 | # (2) run the encoder with: |
---|
51 | # mpeg2encode mpeg2encode.par movie.mpg |
---|
52 | # |
---|
53 | # For tips on how to combine 2 or more sequences of images into one mpeg, see the |
---|
54 | # 'renumber_sequence' script at http://marc.me.utexas.edu/mpeg_tools.html. |
---|
55 | # or use the 'rename' command and see http://www.tux.org/~mayer/linux/book.pdf. |
---|
56 | # |
---|
57 | # |
---|
58 | # Marc Compere |
---|
59 | # CompereM@asme.org |
---|
60 | # created : 18 September 2001 |
---|
61 | # modified: 20 January 2002 |
---|
62 | |
---|
63 | # development arg setup: |
---|
64 | # filelist=(`ls still_frames/test*ppm`) ; echo ${filelist[*]} |
---|
65 | |
---|
66 | |
---|
67 | parameter_set=1 # the PAL (-->2) parameter set is ImageMagick's default, but NTSC (-->1) seems to make |
---|
68 | # smaller mpeg's with similar playback quality |
---|
69 | |
---|
70 | if [ "$1" = "" ]; |
---|
71 | then |
---|
72 | echo " Usage:" |
---|
73 | echo " make_mpeg2encode_parfile filelist" |
---|
74 | echo |
---|
75 | echo " where the 'ppm' or 'yuv' string indicates which intermediate format to specify for mpeg2encode to use," |
---|
76 | echo " and where filelist is the list of filenames, including the directory, where the still frame images reside." |
---|
77 | echo |
---|
78 | echo " Examples:" |
---|
79 | echo " make_mpeg2encode_parfile /tmp/images/*" |
---|
80 | echo " make_mpeg2encode_parfile /tmp/images/scenarioA*.ppm" |
---|
81 | echo " or" |
---|
82 | echo " make_mpeg2encode_parfile yuv /tmp/images/*" |
---|
83 | echo " make_mpeg2encode_parfile ppm /tmp/images/scenarioA*.tif" |
---|
84 | echo |
---|
85 | echo |
---|
86 | echo "TYPICAL ANIMATION STEPS:" |
---|
87 | echo " (1) convert images from their native format to ppm or yuv with:" |
---|
88 | echo " imagetoppm ./images/scenario1*.tif" |
---|
89 | echo " imagetoyuv ./images/scenario1*.tif" |
---|
90 | echo " (2) make the encoder parameter file with:" |
---|
91 | echo " make_mpeg2encode_parfile ./images/scenario1*.ppm (use ppm images here to get image info properly in case padding was required)" |
---|
92 | echo " make_mpeg2encode_parfile ./images/scenario1*.tif (use tif images here if using yuv's to get image info properly)" |
---|
93 | echo " (3) run the encoder with:" |
---|
94 | echo " mpeg2encode mpeg2encode.par scenario1.mpg" $'\n\n' |
---|
95 | else |
---|
96 | |
---|
97 | filelist=($*) |
---|
98 | # assign input filename arglist |
---|
99 | |
---|
100 | if [ "$parameter_set" = "1" ]; |
---|
101 | then |
---|
102 | # set variables for NTSC |
---|
103 | fps=1 # specifying frames per second (this actually comes from frc spec and is only used in the comment string) |
---|
104 | Ngop=4 # 15 for NTSC |
---|
105 | frc=5 # 5 for NTSC |
---|
106 | vidfmt=2 # video format = 1->PAL, 2->NTSC |
---|
107 | Nmatcoef=4 # 5->PAL, 4->NTSC |
---|
108 | elif [ "$parameter_set" = "2" ]; |
---|
109 | then |
---|
110 | # set variables for PAL |
---|
111 | fps=25 # specifying frames per second (this actually comes from frc spec and is only used in the comment string) |
---|
112 | Ngop=12 # 12 for NTSC |
---|
113 | frc=3 # 3 for NTSC |
---|
114 | vidfmt=1 # video format = 1->PAL, 2->NTSC |
---|
115 | Nmatcoef=5 # 5->PAL, 4->NTSC |
---|
116 | else |
---|
117 | echo "mpeg2encode_preproc: invalid parameter_set number",$parameter_set |
---|
118 | echo "mpeg2encode_preproc: parameter_set should be 1 (for NTSC) or 2 (for PAL)" |
---|
119 | echo "mpeg2encode_preproc: exiting...." $'\n\n\n' |
---|
120 | fi |
---|
121 | |
---|
122 | |
---|
123 | # Set the rest of input parameters to write_parfile() |
---|
124 | parfile="mpeg2encode.par" # output parameter file |
---|
125 | statfile="/dev/null" # may be '-' for stdout or /dev/null (default) |
---|
126 | ipff=1 # input picture file format (only 1->yuv3 or 2->ppm used here) |
---|
127 | # note: using ipff=2 for ppm's seems to create skewed animations that appear to have the aspect |
---|
128 | # ratio way off, but changing the aspect ratio in the parameter file seems to do nothing... |
---|
129 | # --> use yuv's as the input file format to mpeg2encode (yuv is the 'convert' default) |
---|
130 | # note: ipff was set at 2 which means using the .ppm image format, but now that option |
---|
131 | # fails and causes mpeg2encode to crash. (?) Go figure. I'm now using the .yuv image format. |
---|
132 | # 10 January 2002 |
---|
133 | |
---|
134 | |
---|
135 | bitrate=1152000.0 # default was 5000000.0 (bits/sec), but 1152000.0 is mo'bettah |
---|
136 | |
---|
137 | |
---|
138 | # find Nframes |
---|
139 | Nframes=-1 # initially 0, but results in one extra filename. weird. |
---|
140 | for i in ${filelist[*]} |
---|
141 | do |
---|
142 | let Nframes=Nframes+1 |
---|
143 | done |
---|
144 | #echo $Nframes |
---|
145 | |
---|
146 | |
---|
147 | # find the common file (and directory name) prefix string to all image files: |
---|
148 | filenamelength=`echo ${filelist[0]} | awk '{print length}'` |
---|
149 | all_match=1 |
---|
150 | char_cnt=0 |
---|
151 | str1=(${filelist[0]}) |
---|
152 | str2=(${filelist[${Nframes}-1]}) |
---|
153 | while [ "${all_match}" = "1" -a "${char_cnt}" -le "${filenamelength}" ] ; do |
---|
154 | if [ "${str1:$char_cnt:1}" = "${str2:$char_cnt:1}" ] ; # compare the characters in the first and last filenames |
---|
155 | then |
---|
156 | #echo "characters in element $char_cnt match" ; |
---|
157 | let char_cnt=char_cnt+1 |
---|
158 | else |
---|
159 | all_match=0 |
---|
160 | #echo "characters in element $char_cnt DO NOT match, exiting..." ; |
---|
161 | fi |
---|
162 | done |
---|
163 | basefilename=${str1:0:$char_cnt} |
---|
164 | restofthefilename=${str1:$char_cnt} |
---|
165 | |
---|
166 | first_num=`echo ${restofthefilename} | awk -F. '{print $1}'` # this assumes the filename has an extension, ".something" |
---|
167 | maxnumchars=`echo $first_num | awk '{print length()}'` |
---|
168 | |
---|
169 | # note: |
---|
170 | # awk's array indicies are 1-based |
---|
171 | # bash's array indicies are 0-based |
---|
172 | |
---|
173 | |
---|
174 | # place hsize and vsize in ${sizes[0]} and ${sizes[1]} |
---|
175 | info=(`identify -ping ${filelist[0]}`) # use ImageMagick's identify command |
---|
176 | sizes=(`echo ${info[2]} | awk -Fx '{print $1}{print $2}'`) |
---|
177 | hsize=${sizes[0]} |
---|
178 | vsize=${sizes[1]} |
---|
179 | |
---|
180 | # determine if hsize is an even number or not... |
---|
181 | hsize_odd=$(( $(( hsize % 2)) ? 1 : 0 )) |
---|
182 | vsize_odd=$(( $(( vsize % 2)) ? 1 : 0 )) |
---|
183 | |
---|
184 | # ... if so, correct it by adding one (mpeg2encode seems to complain otherwise) |
---|
185 | # note: this is *only* useful if you are trying to convert a seqence of odd horizonal- or |
---|
186 | # vertical-sized yuv images. A mismatch in specified yuv image sizes and the actual size |
---|
187 | # used to create the yuv (i.e. from the original tif or gif or whatever) will generate a reasonably |
---|
188 | # acceptable mpeg. However, if ppm images require size-adjustment in the mpeg2encode.par |
---|
189 | # file then you're in touble --> this means the ppm image has been 'identify'ed as an odd-sized image |
---|
190 | # in either it's horizonal or vertical dimension and specifying a different number in the parameter |
---|
191 | # file will generate a bad mpeg. Use imagetoppm to convert the original file into a ppm and, in the |
---|
192 | # process, if hsize or vsize is not even-numbered, imagetoppm will pad the image with 'pnmpad' such |
---|
193 | # that this script will not require adjustment to get even-numbered hzize and vsizes. |
---|
194 | if [ "$hsize_odd" = "1" ]; |
---|
195 | then |
---|
196 | let hsize=hsize+1 |
---|
197 | fi |
---|
198 | if [ "$vsize_odd" = "1" ]; |
---|
199 | then |
---|
200 | let vsize=vsize+1 |
---|
201 | fi |
---|
202 | |
---|
203 | # variable descriptions: |
---|
204 | # fps - frame rate code, specifying frames per second |
---|
205 | # parfile - output parameter file |
---|
206 | # basefilename - text-string common to each filename (not including and leading directory names) |
---|
207 | # maxnumchars - number of characters in the largest number in the sequence, e.g. 2 for 10-99 frames, 3 for 100-999 frames, etc. |
---|
208 | # statfile - may be '-' for stdout (default=/dev/null) |
---|
209 | # ipff - input picture file format (only 1->yuv3 or 2->ppm used here) |
---|
210 | # Nframes - total number of frames (image files) within the sequence |
---|
211 | # Ngop - 12 or 15, number of frames within a Group Of Frames (GOP) |
---|
212 | # hsize - horizonal images size, from ImageMagick's identify command |
---|
213 | # vsize - horizonal images size, from ImageMagick's identify command |
---|
214 | # frc - framerate code, 1,2,3,4, or 5, see mpeg2encode documentation |
---|
215 | # bitrate - bits/sec, see mpeg2encode documentation |
---|
216 | # vidfmt - video format = 1->PAL, 2->NTSC, see mpeg2encode documentation |
---|
217 | # Nmatcoef - 5->PAL, 4->NTSC, see mpeg2encode documentation |
---|
218 | |
---|
219 | echo $'\t' "make_mpeg2encode_parfile: writing $parfile." |
---|
220 | echo "MPEG-1, $fps frames/sec, `date`, parameter file generated by make_mpeg2encode_parfile" > $parfile |
---|
221 | echo "$basefilename%0$maxnumchars""d /* name of source files */" >> $parfile |
---|
222 | echo "- /* name of reconstructed images (\"-\": dont store) */" >> $parfile |
---|
223 | echo "- /* name of intra quant matrix file (\"-\": default matrix) */" >> $parfile |
---|
224 | echo "- /* name of non intra quant matrix file (\"-\": default matrix) */" >> $parfile |
---|
225 | echo "$statfile /* name of statistics file (\"-\": stdout ) */" >> $parfile |
---|
226 | echo "$ipff /* input picture file format: 0=*.Y,*.U,*.V, 1=*.yuv, 2=*.ppm */" >> $parfile |
---|
227 | echo "$Nframes /* number of frames */" >> $parfile |
---|
228 | echo "1 /* number of first frame */" >> $parfile |
---|
229 | echo "00:00:00:00 /* timecode of first frame */" >> $parfile |
---|
230 | echo "$Ngop /* N (# of frames in GOP) */" >> $parfile |
---|
231 | echo "2 /* M (I/P frame distance) */" >> $parfile |
---|
232 | echo "1 /* ISO/IEC 11172-2 stream (0=MPEG-2, 1=MPEG-1)*/" >> $parfile |
---|
233 | echo "0 /* 0:frame pictures, 1:field pictures */" >> $parfile |
---|
234 | echo "${hsize} /* horizontal_size */" >> $parfile |
---|
235 | echo "${vsize} /* vertical_size */" >> $parfile |
---|
236 | echo "8 /* aspect_ratio_information 1=square pel, 2=4:3, 3=16:9, 4=2.11:1 */" >> $parfile |
---|
237 | echo "$frc /* frame_rate_code 1=23.976, 2=24, 3=25, 4=29.97, 5=30 frames/sec. */" >> $parfile |
---|
238 | echo "$bitrate /* bit_rate (bits/s) */" >> $parfile |
---|
239 | echo "112 /* vbv_buffer_size (in multiples of 16 kbit) */" >> $parfile |
---|
240 | echo "0 /* low_delay */" >> $parfile |
---|
241 | echo "1 /* constrained_parameters_flag */" >> $parfile |
---|
242 | echo "4 /* Profile ID: Simple = 5, Main = 4, SNR = 3, Spatial = 2, High = 1 */" >> $parfile |
---|
243 | echo "8 /* Level ID: Low = 10, Main = 8, High 1440 = 6, High = 4 */" >> $parfile |
---|
244 | echo "1 /* progressive_sequence */" >> $parfile |
---|
245 | echo "1 /* chroma_format: 1=4:2:0, 2=4:2:2, 3=4:4:4 */" >> $parfile |
---|
246 | echo "$vidfmt /* video_format: 0=comp., 1=PAL, 2=NTSC, 3=SECAM, 4=MAC, 5=unspec. */" >> $parfile |
---|
247 | echo "5 /* color_primaries */" >> $parfile |
---|
248 | echo "5 /* transfer_characteristics */" >> $parfile |
---|
249 | echo "$Nmatcoef /* matrix_coefficients */" >> $parfile |
---|
250 | echo "$hsize /* display_horizontal_size */" >> $parfile |
---|
251 | echo "$vsize /* display_vertical_size */" >> $parfile |
---|
252 | echo "0 /* intra_dc_precision (0: 8 bit, 1: 9 bit, 2: 10 bit, 3: 11 bit */" >> $parfile |
---|
253 | echo "0 /* top_field_first */" >> $parfile |
---|
254 | echo "1 1 1 /* frame_pred_frame_dct (I P B) */" >> $parfile |
---|
255 | echo "0 0 0 /* concealment_motion_vectors (I P B) */" >> $parfile |
---|
256 | echo "0 0 0 /* q_scale_type (I P B) */" >> $parfile |
---|
257 | echo "0 0 0 /* intra_vlc_format (I P B)*/" >> $parfile |
---|
258 | echo "0 0 0 /* alternate_scan (I P B) */" >> $parfile |
---|
259 | echo "0 /* repeat_first_field */" >> $parfile |
---|
260 | echo "1 /* progressive_frame */" >> $parfile |
---|
261 | echo "0 /* P distance between complete intra slice refresh */" >> $parfile |
---|
262 | echo "0 /* rate control: r (reaction parameter) */" >> $parfile |
---|
263 | echo "0 /* rate control: avg_act (initial average activity) */" >> $parfile |
---|
264 | echo "0 /* rate control: Xi (initial I frame global complexity measure) */" >> $parfile |
---|
265 | echo "0 /* rate control: Xp (initial P frame global complexity measure) */" >> $parfile |
---|
266 | echo "0 /* rate control: Xb (initial B frame global complexity measure) */" >> $parfile |
---|
267 | echo "0 /* rate control: d0i (initial I frame virtual buffer fullness) */" >> $parfile |
---|
268 | echo "0 /* rate control: d0p (initial P frame virtual buffer fullness) */" >> $parfile |
---|
269 | echo "0 /* rate control: d0b (initial B frame virtual buffer fullness) */" >> $parfile |
---|
270 | echo "2 2 11 11 /* P: forw_hor_f_code forw_vert_f_code search_width/height */" >> $parfile |
---|
271 | echo "1 1 3 3 /* B1: forw_hor_f_code forw_vert_f_code search_width/height */" >> $parfile |
---|
272 | echo "1 1 7 7 /* B1: back_hor_f_code back_vert_f_code search_width/height */" >> $parfile |
---|
273 | echo "1 1 7 7 /* B2: forw_hor_f_code forw_vert_f_code search_width/height */" >> $parfile |
---|
274 | echo "1 1 3 3 /* B2: back_hor_f_code back_vert_f_code search_width/height */" >> $parfile ; |
---|
275 | |
---|
276 | |
---|
277 | |
---|
278 | fi # end "if [ "$1" = "" ];" approximately on line 69 |
---|
279 | |
---|