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