1#!/usr/bin/env python 2# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3# 4# Use of this source code is governed by a BSD-style license 5# that can be found in the LICENSE file in the root of the source 6# tree. An additional intellectual property rights grant can be found 7# in the file PATENTS. All contributing project authors may 8# be found in the AUTHORS file in the root of the source tree. 9 10import optparse 11import os 12import sys 13 14 15def _crop_one_frame(yuv_file, output_file, component_sizes): 16 """Crops one frame. 17 18 This function crops one frame going through all the YUV planes and cropping 19 respective amount of rows. 20 21 Args: 22 yuv_file(file): The opened (for binary reading) YUV file. 23 output_file(file): The opened (for binary writing) file. 24 component_sizes(list of 3 3-ples): The list contains the sizes for all the 25 planes (Y, U, V) of the YUV file plus the crop_height scaled for every 26 plane. The sizes equal width, height and crop_height for the Y plane, 27 and are equal to width/2, height/2 and crop_height/2 for the U and V 28 planes. 29 Return: 30 (bool): True if there are more frames to crop, False otherwise. 31 """ 32 for comp_width, comp_height, comp_crop_height in component_sizes: 33 for row in range(comp_height): 34 # Read the plane data for this row. 35 yuv_plane = yuv_file.read(comp_width) 36 37 # If the plane is empty, we have reached the end of the file. 38 if yuv_plane == "": 39 return False 40 41 # Only write the plane data for the rows bigger than crop_height. 42 if row >= comp_crop_height: 43 output_file.write(yuv_plane) 44 return True 45 46 47def crop_frames(yuv_file_name, output_file_name, width, height, crop_height): 48 """Crops rows of pixels from the top of the YUV frames. 49 50 This function goes through all the frames in a video and crops the crop_height 51 top pixel rows of every frame. 52 53 Args: 54 yuv_file_name(string): The name of the YUV file to be cropped. 55 output_file_name(string): The name of the output file where the result will 56 be written. 57 width(int): The width of the original YUV file. 58 height(int): The height of the original YUV file. 59 crop_height(int): The height (the number of pixel rows) to be cropped from 60 the frames. 61 """ 62 # Component sizes = [Y_sizes, U_sizes, V_sizes]. 63 component_sizes = [(width, height, crop_height), 64 (width/2, height/2, crop_height/2), 65 (width/2, height/2, crop_height/2)] 66 67 yuv_file = open(yuv_file_name, 'rb') 68 output_file = open(output_file_name, 'wb') 69 70 data_left = True 71 while data_left: 72 data_left = _crop_one_frame(yuv_file, output_file, component_sizes) 73 74 yuv_file.close() 75 output_file.close() 76 77 78def _parse_args(): 79 """Registers the command-line options.""" 80 usage = "usage: %prog [options]" 81 parser = optparse.OptionParser(usage=usage) 82 83 parser.add_option('--width', type='int', 84 default=352, 85 help=('Width of the YUV file\'s frames. ' 86 'Default: %default')) 87 parser.add_option('--height', type='int', default=288, 88 help=('Height of the YUV file\'s frames. ' 89 'Default: %default')) 90 parser.add_option('--crop_height', type='int', default=32, 91 help=('How much of the top of the YUV file to crop. ' 92 'Has to be module of 2. Default: %default')) 93 parser.add_option('--yuv_file', type='string', 94 help=('The YUV file to be cropped.')) 95 parser.add_option('--output_file', type='string', default='output.yuv', 96 help=('The output YUV file containing the cropped YUV. ' 97 'Default: %default')) 98 options = parser.parse_args()[0] 99 if not options.yuv_file: 100 parser.error('yuv_file argument missing. Please specify input YUV file!') 101 return options 102 103 104def _main(): 105 """A tool to crop rows of pixels from the top part of a YUV file. 106 107 A simple invocation will be: 108 ./yuv_cropper.py --width=640 --height=480 --crop_height=32 109 --yuv_file=<path_and_name_of_yuv_file> 110 --output_yuv=<path and name_of_output_file> 111 """ 112 options = _parse_args() 113 114 if os.path.getsize(options.yuv_file) == 0: 115 sys.stderr.write('Error: The YUV file you have passed has size 0. The ' 116 'produced output will also have size 0.\n') 117 return -1 118 119 crop_frames(options.yuv_file, options.output_file, options.width, 120 options.height, options.crop_height) 121 return 0 122 123 124if __name__ == '__main__': 125 sys.exit(_main()) 126