annotate aviwrite.c @ 1455:b2f3962d0e0e

interleaved AVI: audio preload PTS compensation
author arpi
date Mon, 06 Aug 2001 23:59:22 +0000
parents 8511095c5283
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
587
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
1
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
2 #include <stdio.h>
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
3 #include <stdlib.h>
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
4 #include <unistd.h>
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
5
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
6 #include "wine/mmreg.h"
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
7 #include "wine/avifmt.h"
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
8 #include "wine/vfw.h"
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
9
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
10 extern char* encode_name;
8511095c5283 stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents: 1
diff changeset
11 extern char* encode_index_name;
1
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
12
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
13 void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
14
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
15 fwrite(&id,4,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
16 fwrite(&len,4,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
17 if(len>0){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
18 if(data){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
19 // DATA
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
20 fwrite(data,len,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
21 if(len&1){ // padding
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
22 unsigned char zerobyte=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
23 fwrite(&zerobyte,1,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
24 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
25 } else {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
26 // JUNK
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
27 char *avi_junk_data="[= MPlayer junk data! =]";
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
28 if(len&1) ++len; // padding
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
29 while(len>0){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
30 int l=strlen(avi_junk_data);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
31 if(l>len) l=len;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
32 fwrite(avi_junk_data,l,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
33 len-=l;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
34 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
35 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
36 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
37
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
38 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
39
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
40
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
41 void write_avi_list(FILE *f,unsigned int id,int len){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
42 unsigned int list_id=FOURCC_LIST;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
43 len+=4; // list fix
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
44 fwrite(&list_id,4,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
45 fwrite(&len,4,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
46 fwrite(&id,4,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
47 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
48
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
49 struct {
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
50 MainAVIHeader avih;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
51 AVIStreamHeader video;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
52 BITMAPINFOHEADER bih;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
53 unsigned int movi_start;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
54 unsigned int movi_end;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
55 unsigned int file_end;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
56 } wah;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
57
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
58 void write_avi_header(FILE *f){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
59 unsigned int riff[3];
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
60 // RIFF header:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
61 riff[0]=mmioFOURCC('R','I','F','F');
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
62 riff[1]=wah.file_end; // filesize
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
63 riff[2]=formtypeAVI; // 'AVI '
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
64 fwrite(&riff,12,1,f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
65 // AVI header:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
66 write_avi_list(f,listtypeAVIHEADER,sizeof(wah.avih)+8+12+sizeof(wah.video)+8+sizeof(wah.bih)+8);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
67 write_avi_chunk(f,ckidAVIMAINHDR,sizeof(wah.avih),&wah.avih);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
68 // stream header:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
69 write_avi_list(f,listtypeSTREAMHEADER,sizeof(wah.video)+8+sizeof(wah.bih)+8);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
70 write_avi_chunk(f,ckidSTREAMHEADER,sizeof(wah.video),&wah.video);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
71 write_avi_chunk(f,ckidSTREAMFORMAT,sizeof(wah.bih),&wah.bih);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
72 // JUNK:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
73 write_avi_chunk(f,ckidAVIPADDING,2048-(ftell(f)&2047)-8,NULL);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
74 // 'movi' header:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
75 write_avi_list(f,listtypeAVIMOVIE,wah.movi_end-ftell(f)-12);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
76 wah.movi_start=ftell(f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
77 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
78
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
79 // called _before_ encoding: (write placeholders and video info)
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
80 void write_avi_header_1(FILE *f,int fcc,float fps,int width,int height){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
81 int frames=8*3600*fps; // 8 hours
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
82
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
83 wah.file_end=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
84 wah.movi_end=0x7f000000;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
85
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
86 wah.avih.dwMicroSecPerFrame=1000000.0f/fps;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
87 wah.avih.dwMaxBytesPerSec=fps*500000; // ?????
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
88 wah.avih.dwPaddingGranularity=1; // padding
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
89 wah.avih.dwFlags=AVIF_ISINTERLEAVED;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
90 wah.avih.dwTotalFrames=frames;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
91 wah.avih.dwInitialFrames=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
92 wah.avih.dwStreams=1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
93 wah.avih.dwSuggestedBufferSize=0x10000; // 1MB
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
94 wah.avih.dwWidth=width;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
95 wah.avih.dwHeight=height;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
96 wah.avih.dwReserved[0]=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
97 wah.avih.dwReserved[1]=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
98 wah.avih.dwReserved[2]=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
99 wah.avih.dwReserved[3]=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
100
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
101 wah.video.fccType=streamtypeVIDEO;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
102 wah.video.fccHandler=fcc;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
103 wah.video.dwFlags=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
104 wah.video.wPriority=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
105 wah.video.wLanguage=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
106 wah.video.dwInitialFrames=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
107 wah.video.dwScale=10000;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
108 wah.video.dwRate=fps*10000;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
109 wah.video.dwStart=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
110 wah.video.dwLength=frames;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
111 wah.video.dwSuggestedBufferSize=0x100000; // 1MB ????
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
112 wah.video.dwQuality=10000;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
113 wah.video.dwSampleSize=width*height*3;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
114
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
115 wah.bih.biSize=sizeof(wah.bih); // 40 ?
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
116 wah.bih.biWidth=width;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
117 wah.bih.biHeight=height;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
118 wah.bih.biPlanes=1;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
119 wah.bih.biBitCount=24;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
120 wah.bih.biCompression=fcc;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
121 wah.bih.biSizeImage=3*width*height;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
122 wah.bih.biXPelsPerMeter=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
123 wah.bih.biYPelsPerMeter=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
124 wah.bih.biClrUsed=
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
125 wah.bih.biClrImportant=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
126
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
127 write_avi_header(f);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
128 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
129
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
130 void avi_fixate(){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
131 // append index and fix avi headers:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
132 FILE *f1=fopen(encode_name,"r+");
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
133 FILE *f2;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
134
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
135 if(!f1) return; // error
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
136
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
137 fseek(f1,0,SEEK_END);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
138 wah.file_end=wah.movi_end=ftell(f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
139
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
140 // index:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
141 if(encode_index_name && (f2=fopen(encode_index_name,"rb"))){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
142 AVIINDEXENTRY idx;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
143 unsigned int pos=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
144 int frames=0;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
145 write_avi_chunk(f1,ckidAVINEWINDEX,0,NULL);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
146 while(fread(&idx,sizeof(idx),1,f2)>0){
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
147 idx.dwChunkOffset-=wah.movi_start-4;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
148 fwrite(&idx,sizeof(idx),1,f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
149 ++frames;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
150 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
151 fclose(f2);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
152 unlink(encode_index_name);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
153 wah.file_end=ftell(f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
154 // re-write idx1 length:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
155 pos=wah.file_end-wah.movi_end-8;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
156 fseek(f1,wah.movi_end+4,SEEK_SET);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
157 fwrite(&pos,4,1,f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
158 // fixup frames:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
159 wah.avih.dwTotalFrames=frames;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
160 wah.video.dwLength=frames;
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
161 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
162
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
163 // re-write avi header:
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
164 fseek(f1,0,SEEK_SET);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
165 write_avi_header(f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
166
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
167 fclose(f1);
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
168
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
169 }
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
170
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
171
3b5f5d1c5041 Initial revision
arpi_esp
parents:
diff changeset
172