repair flickering video encode, bug created last checkin
[goodguy/history.git] / cinelerra-5.0 / quicktime / raw.c
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include "graphics.h"
5
6 typedef struct
7 {
8         unsigned char *temp_frame;  /* For changing color models and scaling */
9         unsigned char **temp_rows;
10 } quicktime_raw_codec_t;
11
12
13 static void quicktime_delete_codec_raw(quicktime_video_map_t *vtrack)
14 {
15         quicktime_raw_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
16         if(codec->temp_frame)
17         {
18                 free(codec->temp_frame);
19                 free(codec->temp_rows);
20         }
21         free(codec);
22 }
23
24 static int source_cmodel(quicktime_t *file, int track)
25 {
26         int depth = quicktime_video_depth(file, track);
27         if(depth == 24) 
28                 return BC_RGB888;
29         else
30                 return BC_ARGB8888;
31 }
32
33 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
34 {
35         int result = 0;
36         quicktime_trak_t *trak = file->vtracks[track].track;
37         int height = trak->tkhd.track_height;
38         int width = trak->tkhd.track_width;
39         long bytes;
40         int i;
41         quicktime_raw_codec_t *codec = ((quicktime_codec_t*)file->vtracks[track].codec)->priv;
42         int cmodel = source_cmodel(file, track);
43         int use_temp = (cmodel != file->color_model ||
44                 file->in_x != 0 ||
45                 file->in_y != 0 ||
46                 file->in_w != width ||
47                 file->in_h != height ||
48                 file->out_w != width ||
49                 file->out_h != height);
50         unsigned char *temp_data;
51         unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
52
53         if(use_temp)
54         {
55                 if(!codec->temp_frame)
56                 {
57                         codec->temp_frame = malloc(cmodel_calculate_datasize(width, 
58                                         height, 
59                                         -1, 
60                                         cmodel));
61                 }
62                 for(i = 0; i < height; i++)
63                         temp_rows[i] = codec->temp_frame + 
64                                 cmodel_calculate_pixelsize(cmodel) * width * i;
65                 temp_data = codec->temp_frame;
66         }
67         else
68         {
69                 temp_data = row_pointers[0];
70                 for(i = 0; i < height; i++)
71                         temp_rows[i] = row_pointers[i];
72         }
73
74
75 /* Read data */
76         quicktime_set_video_position(file, file->vtracks[track].current_position, track);
77         bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);
78         result = !quicktime_read_data(file, (char*)temp_data, bytes);
79
80 /* Convert colormodel */
81         if(use_temp)
82         {
83                 cmodel_transfer(row_pointers, 
84                         temp_rows,
85                         row_pointers[0],
86                         row_pointers[1],
87                         row_pointers[2],
88                         0,
89                         0,
90                         0,
91                         file->in_x, 
92                         file->in_y, 
93                         file->in_w, 
94                         file->in_h,
95                         0, 
96                         0, 
97                         file->out_w, 
98                         file->out_h,
99                         cmodel, 
100                         file->color_model,
101                         0,
102                         width,
103                         file->out_w);
104         }
105
106         free(temp_rows);
107
108         return result;
109 }
110
111 static int encode(quicktime_t *file, 
112         unsigned char **row_pointers, 
113         int track)
114 {
115 //      int64_t offset = quicktime_position(file);
116         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
117         quicktime_raw_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
118         quicktime_trak_t *trak = vtrack->track;
119         int i, result;
120         int height = trak->tkhd.track_height;
121         int width = trak->tkhd.track_width;
122         int depth = quicktime_video_depth(file, track);
123         int dest_cmodel;
124         quicktime_atom_t chunk_atom;
125
126 //printf("quicktime_encode_raw %llx %llx\n", file->file_position, file->ftell_position);
127         if(depth == 32)
128         {
129                 dest_cmodel = BC_ARGB8888;
130
131         }
132         else
133         {
134                 dest_cmodel = BC_RGB888;
135         }
136
137
138
139
140         if(file->color_model != dest_cmodel)
141         {
142                 if(!codec->temp_frame)
143                 {
144                         int size = cmodel_calculate_datasize(width, height, -1, dest_cmodel);
145                         int row_size = cmodel_calculate_pixelsize(dest_cmodel) * width;
146                         codec->temp_frame = malloc(size);
147                         codec->temp_rows = malloc(sizeof(unsigned char*) * height);
148                         for(i = 0; i < height; i++)
149                                 codec->temp_rows[i] = codec->temp_frame + i*row_size;
150                 }
151                 
152                 
153                 
154                 cmodel_transfer(codec->temp_rows, /* Leave NULL if non existent */
155                         row_pointers,
156                         0, /* Leave NULL if non existent */
157                         0,
158                         0,
159                         row_pointers[0], /* Leave NULL if non existent */
160                         row_pointers[1],
161                         row_pointers[2],
162                         0,        /* Dimensions to capture from input frame */
163                         0, 
164                         width, 
165                         height,
166                         0,       /* Dimensions to project on output frame */
167                         0,
168                         width, 
169                         height,
170                         file->color_model, 
171                         dest_cmodel,
172                         0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
173                         width,       /* For planar use the luma rowspan */
174                         width);     /* For planar use the luma rowspan */
175
176                 quicktime_write_chunk_header(file, trak, &chunk_atom);
177                 result = !quicktime_write_data(file, (char*)codec->temp_frame, 
178                         cmodel_calculate_datasize(width, height, -1, dest_cmodel));
179                 quicktime_write_chunk_footer(file, trak,
180                         vtrack->current_chunk, &chunk_atom, 1);
181         }
182         else
183         {
184                 quicktime_write_chunk_header(file, trak, &chunk_atom);
185                 result = !quicktime_write_data(file, (char*)row_pointers[0], 
186                         cmodel_calculate_datasize(width, height, -1, file->color_model));
187                 quicktime_write_chunk_footer(file, trak,
188                         vtrack->current_chunk, &chunk_atom, 1);
189         }
190
191
192         vtrack->current_chunk++;
193         return result;
194 }
195
196 int quicktime_raw_rows_consecutive(unsigned char **row_pointers, int w, int h, int depth)
197 {
198         int i, result;
199 /* see if row_pointers are consecutive */
200         for(i = 1, result = 1; i < h; i++)
201         {
202                 if(row_pointers[i] - row_pointers[i - 1] != w * depth) result = 0;
203         }
204         return result;
205 }
206
207 static int reads_colormodel(quicktime_t *file, 
208                 int colormodel, 
209                 int track)
210 {
211         return (colormodel == BC_RGB888 ||
212                 colormodel == BC_BGR8888);
213 }
214
215 void quicktime_init_codec_raw(quicktime_video_map_t *vtrack)
216 {
217         quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
218
219         codec_base->priv = calloc(1, sizeof(quicktime_raw_codec_t));
220         codec_base->delete_vcodec = quicktime_delete_codec_raw;
221         codec_base->decode_video = decode;
222         codec_base->encode_video = encode;
223         codec_base->decode_audio = 0;
224         codec_base->encode_audio = 0;
225         codec_base->reads_colormodel = reads_colormodel;
226         codec_base->fourcc = QUICKTIME_RAW;
227         codec_base->title = "RGB uncompressed";
228         codec_base->desc = "RGB uncompressed";
229 }