#include <iostream>
#include <opencv2/opencv.hpp>
#include <cstdlib>
using namespace std;



int main(int argc, char **argv){

	if (argc<3){
		cout << "Usage: ./grayvideo input.mp4 output.mp4" <<endl;
		return -1;
	}
	cv::VideoCapture cap(argv[1]);
	if(!cap.isOpened()){
		cout <<"error opening the file" <<endl;
		return -1;
	}


	int width=cap.get(cv::CAP_PROP_FRAME_WIDTH);
	int height=cap.get(cv::CAP_PROP_FRAME_HEIGHT);
	int fps=cap.get(cv::CAP_PROP_FPS);
	if(fps<=0) fps=30;
	cv::VideoWriter writer (argv[2],cv::VideoWriter::fourcc('a','v','c','1'),fps,cv::Size(width,height));
	if(!writer.isOpened()){
		cout <<"Error, writting file" <<endl;
		return -1;
		}
	cv::Mat frame;
	while (cap.read(frame)){
		int rows=frame.rows;
		int cols=frame.cols;
		int channels=3;
		//allocating cuntinuous memory chunk
		uint8_t *p= new uint8_t [rows*cols*channels];
		//copy frame into continuos memory
		for (int i=0; i<rows; i++){
			for (int j=0; j<cols; j++){
				cv::Vec3b pixel= frame.at<cv::Vec3b>(i,j);
				int base=(i*cols+j)*3;
				p[base+0]=pixel[0];
				p[base+1]=pixel[1];
				p[base+2]-pixel[2];
				}
			}
		//grayscale transform
		for (int i=0; i<rows; i++){
			for (int j=0; j<cols; j++){
				int base=(i*cols+j)*3;
				uint8_t B=p[base+0];
				uint8_t G=p[base+1];
				uint8_t R=p[base+2];
				uint8_t gray=(uint8_t) 0.299*R + 0.587*G + 0.114*G;
				p[base+0]=gray;
				p[base+1]=gray;
				p[base+2}=gray;
				}
		}

		//copy back output.mp4
		for (int i=0; i<rows; i++){
			for (int j=0; j<cols; j++){
				int base=(i*cols+j)*3;
				frame.at<cv::Vec3b>(i,j)[0]=p[base+0];
				frame.at<cv::Vec3b>(i,j)[1]=p[base+1];
				frame.at<cv::Vec3b>(i,j)[2]=p[base+2];
				}
			}

		writer.write(frame);
		delete[] p;

		}
		//EOF while
		cap.release();
		writer.release();
		cout <<"video transform success!" <<endl;
		
return 0;
};

