comparison libmpdemux/aviwrite.c @ 2310:9e059416eea6

libdemuxer...
author arpi
date Sat, 20 Oct 2001 18:49:08 +0000
parents aviwrite.c@8511095c5283
children 266dab71162b
comparison
equal deleted inserted replaced
2309:3128b9d8b4ea 2310:9e059416eea6
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5
6 #include "wine/mmreg.h"
7 #include "wine/avifmt.h"
8 #include "wine/vfw.h"
9
10 extern char* encode_name;
11 extern char* encode_index_name;
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