/*******************************************************************
           CF - count frame number and show picture header
 *******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include "mpeg_io.h"
#include "picture_header.h"
#include "sequence_header.h"
#include "timecode.h"

void cf(char *path);
void show_mpeg_video_info(SEQUENCE_HEADER *in, FILE *out);
void show_time(time_t t, FILE *out);

int main(int argc, char **argv)
{
	time_t t;
	
	if(argc < 2){
		fprintf(stderr, "Usage:\n");
		fprintf(stderr, "%s mpeg2video", argv[0]);
		exit(EXIT_FAILURE);
	}

	t = time(NULL);
	
	cf(argv[1]);

	fprintf(stderr, "elapsed time: ");
	show_time(time(NULL) - t, stderr);
	fprintf(stderr, "\n");
	
	return EXIT_SUCCESS;
}

void cf(char *path)
{
	int GOP;
	MPEG_IO p;
	SEQUENCE_HEADER seq;
	PICTURE_HEADER pic;
	int code;
	int frame;
	char picture_type[8] = {
		' ', 'I', 'P', 'B', 'D', ' ', ' ',
	};

	if(!open_mpeg_file(path, &p)){
		fprintf(stderr, "%s - can't open\n", path);
		exit(EXIT_FAILURE);
	}

	if(!next_marker(&p)){
		fprintf(stderr, "%s - is not MPEG file\n", path);
		exit(EXIT_FAILURE);
	}

	code = get_bits(&p, 32);
	if(code != 0x1B3){
		fprintf(stderr, "%s - is not MPEG Video file\n", path);
		fprintf(stderr, "[DEBUG] code=%d\n", code);
		exit(EXIT_FAILURE);
	}

	if(!read_sequence_header(&p, &seq)){
		fprintf(stderr, "%s - has invalid sequence header\n", path);
		exit(EXIT_FAILURE);
	}

	show_mpeg_video_info(&seq, stdout);

	frame = 0;
	
	while(next_marker(&p)){
		code = get_bits(&p, 32);
		if(code == 0x100){
			frame += 1;
			read_picture_header(&p, &pic);
			fprintf(stdout, "%d, %d, %c, %d\n", frame, pic.temporal_reference, picture_type[pic.picture_coding_type], mpeg_io_tell(&p));
		}
	}
			
	fprintf(stdout, "total frame %d\n", frame);

	close_mpeg_file(&p);

}
	
void show_mpeg_video_info(SEQUENCE_HEADER *in, FILE *out)
{
	static const char yuv[4][16] = {
		"invalid",
		"4:2:0",
		"4:2:2",
		"4:4:4",
	};
	
	fprintf(out, "%dx%d, ", in->h_size, in->v_size);
	fprintf(out, "%d.%d fps, ", in->fps.frame / in->fps.scale, ((in->fps.frame % in->fps.scale) * 1000 / in->fps.scale));
	fprintf(out, "%d bps, ", in->bit_rate * 400);
	if(in->mpeg1){
		fprintf(out, "MPEG-1 Video\n");
	}else{
		if(in->se.progressive){
			fprintf(out, "Progressive");
		}else{
			fprintf(out, "Interlace");
		}
		fprintf(out, " MPEG-2 Video");
		fprintf(out, " YUV=%s\n", yuv[in->se.chroma_format]);
	}
}

void show_time(time_t t, FILE *out)
{
	int dd,hh,mm,ss;

	ss = t % 60;
	mm = t / 60 % 60;
	hh = t / 60 / 60 % 24;
	dd = t / 60 / 60 / 24;

	if(dd){
		fprintf(out, "%02d:%02d:%02d:%02d", dd,hh,mm,ss);
	}else{
		fprintf(out, "%02d:%02d:%02d", hh,mm,ss);
	}
}
