1 /*******************************************************************************
2  testqt.c
3 
4  libquicktime - A library for reading and writing quicktime/avi/mp4 files.
5  http://libquicktime.sourceforge.net
6 
7  Copyright (C) 2002 Heroine Virtual Ltd.
8  Copyright (C) 2002-2011 Members of the libquicktime project.
9 
10  This library is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free
12  Software Foundation; either version 2.1 of the License, or (at your option)
13  any later version.
14 
15  This library is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  details.
19 
20  You should have received a copy of the GNU Lesser General Public License along
21  with this library; if not, write to the Free Software Foundation, Inc., 51
22  Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *******************************************************************************/
24 
25 #include "lqt_private.h"
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <math.h>
29 
main(int argc,char ** argv)30 int main(int argc, char** argv)
31 {
32 	char *pcInputFN = argv[1];
33 	char *pcOutputFN = argv[2];
34 	char *pcAudioPrefix = argv[3];
35 	int i;
36 
37 	quicktime_t *pxQuicktimeInput;
38 	quicktime_t *pxQuicktimeOutput;
39 
40 	if( argc != 4 )
41 	{
42 		printf( "usage: testqt <input file> <video output file> <audio output prefix>\n"
43 				"\tReads input file and dumps the video from it to the video\n"
44 				"\toutput file as a raw RGB MOV and the audio as a\n"
45 				"\t<prefix>-<channel #>.sw for each channel. The audio files\n"
46 				"\tare raw 16bit mono at the sampling rate of the original\n"
47 			);
48 		exit(3);
49 	}
50 
51 	pxQuicktimeInput = quicktime_open( pcInputFN, 1, 0 );
52 	if( pxQuicktimeInput == NULL )
53 	{
54 		printf( "Error opening: %s\n", pcInputFN );
55 		exit(1);
56 	}
57 
58 	pxQuicktimeOutput = quicktime_open( pcOutputFN, 0, 1 );
59 	if( pxQuicktimeOutput == NULL )
60 	{
61 		printf( "Error opening: %s\n", pcOutputFN );
62 		exit(2);
63 	}
64 
65 	{
66 		int iFrameWidth = quicktime_video_width( pxQuicktimeInput, 0 );
67 		int iFrameHeight = quicktime_video_height( pxQuicktimeInput, 0 );
68 		float fFrameRate = quicktime_frame_rate( pxQuicktimeInput, 0 );
69 		unsigned char **ppFrameBuffer;
70 		unsigned char *pFrameBufferLinear;
71 		int iFrameNum = 0;
72 		int iSamplesPerFrame =
73 			ceilf( quicktime_sample_rate( pxQuicktimeInput, 0 ) / fFrameRate );
74 		int iNAudioOutputs = lqt_total_channels( pxQuicktimeInput );
75 		FILE **pxAudioOutputs;
76 		int16_t **ppiAudioBuffer;
77 		int16_t *piAudioBufferLinear;
78 
79 		if( fFrameRate <= 0 )
80 			iSamplesPerFrame =
81 				ceilf( quicktime_sample_rate( pxQuicktimeInput, 0 ) );
82 
83 
84 		{
85 			int cpus = 1;
86 			if( getenv("CPUS") != NULL )
87 				cpus = atoi(getenv("CPUS"));
88 			quicktime_set_cpus( pxQuicktimeInput, cpus );
89 			quicktime_set_cpus( pxQuicktimeOutput, cpus );
90 		}
91 
92 		quicktime_set_video( pxQuicktimeOutput, 1, iFrameWidth, iFrameHeight,
93 							 fFrameRate, QUICKTIME_MJPA );
94 
95 		pFrameBufferLinear = malloc( iFrameHeight * iFrameWidth * 3 *
96 									 sizeof( unsigned char ) + 1000 );
97 
98 		ppFrameBuffer = calloc( iFrameHeight, sizeof( unsigned char * ) );
99 		for( i = 0; i < iFrameHeight; i++ )
100 		{
101 			ppFrameBuffer[i] = pFrameBufferLinear + (iFrameWidth * 3 * i);
102 		}
103 
104 		pxAudioOutputs = malloc( iNAudioOutputs * sizeof( FILE * ) );
105 
106 		//piAudioBuffer = malloc( iSamplesPerFrame * sizeof( int16_t ) );
107 		piAudioBufferLinear = malloc( iNAudioOutputs * iSamplesPerFrame
108 									  * sizeof( int16_t ) );
109 
110 		ppiAudioBuffer = calloc( iNAudioOutputs, sizeof( int16_t * ) );
111 		for( i = 0; i < iNAudioOutputs; i++ )
112 		{
113 			//ppiAudioBuffer[i] = malloc( iSamplesPerFrame * sizeof( int16_t ) );
114 			ppiAudioBuffer[i] = piAudioBufferLinear + (iSamplesPerFrame * i);
115 		}
116 
117 		for( i = 0; i < iNAudioOutputs; i++ )
118 		{
119 			char sName[64];
120 			snprintf( sName, 64, "%s-%02d.sw", pcAudioPrefix, i );
121 			pxAudioOutputs[i] = fopen( sName, "wb" );
122 		}
123 
124 		/*
125 		  ppFrameBuffer = calloc( iFrameHeight, sizeof( unsigned char * ) );
126 		  for( i = 0; i < iFrameHeight; i++ )
127 		  {
128 		  ppFrameBuffer[i] =  calloc( iFrameWidth * 3, sizeof( unsigned char ) );
129 		  }
130 		*/
131 
132 		while( iFrameNum < quicktime_video_length( pxQuicktimeInput, 0 )
133 			   || iFrameNum*iSamplesPerFrame < quicktime_audio_length( pxQuicktimeInput, 0 ) )
134 		{
135 			//long int iAudioPos = quicktime_audio_position( pxQuicktimeInput, 0 );
136 			if( iFrameNum < quicktime_video_length( pxQuicktimeInput, 0 ) )
137 			{
138 				quicktime_decode_video( pxQuicktimeInput, ppFrameBuffer, 0 );
139 				quicktime_encode_video( pxQuicktimeOutput, ppFrameBuffer, 0 );
140 				printf( "v " );
141 			}
142 
143 			if( iFrameNum*iSamplesPerFrame < quicktime_audio_length( pxQuicktimeInput, 0 ) )
144 			{
145 				lqt_decode_audio( pxQuicktimeInput, ppiAudioBuffer,
146 								  NULL, iSamplesPerFrame );
147 
148 				for( i = 0; i < iNAudioOutputs; i++ )
149 				{
150 				/*
151 				quicktime_set_audio_position( pxQuicktimeInput, iAudioPos, 0 );
152 				quicktime_decode_audio( pxQuicktimeInput, ppiAudioBuffer[0],
153 				NULL, iSamplesPerFrame, i );
154 				*/
155 
156 					fwrite( ppiAudioBuffer[i], iSamplesPerFrame,
157 							sizeof( int16_t ),
158 							pxAudioOutputs[i] );
159 				}
160 				printf( "a %d(%d) < %ld ", iFrameNum*iSamplesPerFrame, iSamplesPerFrame, quicktime_audio_length( pxQuicktimeInput, 0 ) );
161 			}
162 
163 			printf( "At frame #%d\n", iFrameNum );
164 
165 			iFrameNum++;
166 		}
167 
168 		for( i = 0; i < iNAudioOutputs; i++ )
169 		{
170 			fclose( pxAudioOutputs[i] );
171 		}
172 
173 	}
174 
175 	quicktime_close(pxQuicktimeOutput);
176 	quicktime_close(pxQuicktimeInput);
177 
178 
179 	return 0;
180 }
181