1 #include "colormodels.h"
2 #include "funcprotos.h"
4 #include "workarounds.h"
10 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
15 cmodel_yuv_t yuv_table
;
17 unsigned char *work_buffer
;
19 } quicktime_yv12_codec_t
;
21 static int delete_codec(quicktime_video_map_t
*vtrack
)
23 quicktime_yv12_codec_t
*codec
;
25 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
26 free(codec
->work_buffer
);
31 static int reads_colormodel(quicktime_t
*file
,
35 return (colormodel
== BC_RGB888
||
36 colormodel
== BC_YUV888
||
37 colormodel
== BC_YUV420P
);
40 static int writes_colormodel(quicktime_t
*file
,
44 return (colormodel
== BC_YUV420P
);
47 static void initialize(quicktime_video_map_t
*vtrack
)
49 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
50 quicktime_yv12_codec_t
*codec
= codec_base
->priv
;
51 if(!codec
->initialized
)
53 /* Init private items */
54 codec
->coded_w
= (int)(vtrack
->track
->tkhd
.track_width
/ 2);
56 codec
->coded_h
= (int)(vtrack
->track
->tkhd
.track_height
/ 2);
58 cmodel_init_yuv(&codec
->yuv_table
);
59 codec
->work_buffer
= malloc(codec
->coded_w
* codec
->coded_h
+
60 codec
->coded_w
* codec
->coded_h
/ 2);
61 codec
->initialized
= 1;
65 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
68 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
69 quicktime_yv12_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
70 int width
= vtrack
->track
->tkhd
.track_width
;
71 int height
= vtrack
->track
->tkhd
.track_height
;
72 unsigned char *buffer
;
73 unsigned char *output_row0
, *output_row1
, *y_plane0
, *y_plane1
, *u_plane
, *v_plane
;
74 int64_t y_size
, u_size
, v_size
;
76 int y1
, u
, v
, y2
, r
, g
, b
, y3
, y4
;
78 int bytes_per_row
= width
* cmodel_calculate_pixelsize(file
->color_model
);
81 y_size
= codec
->coded_h
* codec
->coded_w
;
82 u_size
= codec
->coded_h
* codec
->coded_w
/ 4;
83 v_size
= codec
->coded_h
* codec
->coded_w
/ 4;
85 vtrack
->track
->tkhd
.track_width
;
86 quicktime_set_video_position(file
, vtrack
->current_position
, track
);
87 bytes
= quicktime_frame_size(file
, vtrack
->current_position
, track
);
90 if(file
->color_model
== BC_YUV420P
&&
93 file
->in_w
== width
&&
94 file
->in_h
== height
&&
95 file
->out_w
== width
&&
96 file
->out_h
== height
)
98 result
= !quicktime_read_data(file
, row_pointers
[0], y_size
);
99 result
= !quicktime_read_data(file
, row_pointers
[1], u_size
);
100 result
= !quicktime_read_data(file
, row_pointers
[2], v_size
);
104 result
= !quicktime_read_data(file
, codec
->work_buffer
, bytes
);
105 cmodel_transfer(row_pointers
,
111 codec
->work_buffer
+ y_size
,
112 codec
->work_buffer
+ y_size
+ u_size
,
131 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
133 int64_t offset
= quicktime_position(file
);
134 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
135 quicktime_yv12_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
136 quicktime_trak_t
*trak
= vtrack
->track
;
138 int width
= vtrack
->track
->tkhd
.track_width
;
139 int height
= vtrack
->track
->tkhd
.track_height
;
140 unsigned char *y_plane0
, *y_plane1
, *u_plane
, *v_plane
;
141 int64_t y_size
, u_size
, v_size
;
142 unsigned char *input_row0
, *input_row1
;
144 int y1
, u
, y2
, v
, y3
, y4
, subscript
;
146 int64_t bytes
= (int64_t)0;
147 quicktime_atom_t chunk_atom
;
150 y_size
= codec
->coded_h
* codec
->coded_w
;
151 u_size
= codec
->coded_h
* codec
->coded_w
/ 4;
152 v_size
= codec
->coded_h
* codec
->coded_w
/ 4;
153 bytes
= quicktime_add3(y_size
, u_size
, v_size
);
155 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
156 if(file
->color_model
== BC_YUV420P
)
158 result
= !quicktime_write_data(file
, row_pointers
[0], y_size
);
159 if(!result
) result
= !quicktime_write_data(file
, row_pointers
[1], u_size
);
160 if(!result
) result
= !quicktime_write_data(file
, row_pointers
[2], v_size
);
167 codec
->work_buffer
+ y_size
,
168 codec
->work_buffer
+ y_size
+ u_size
,
185 result
= !quicktime_write_data(file
, codec
->work_buffer
, bytes
);
188 quicktime_write_chunk_footer(file
,
190 vtrack
->current_chunk
,
194 vtrack
->current_chunk
++;
198 void quicktime_init_codec_yv12(quicktime_video_map_t
*vtrack
)
201 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
203 /* Init public items */
204 codec_base
->priv
= calloc(1, sizeof(quicktime_yv12_codec_t
));
205 codec_base
->delete_vcodec
= delete_codec
;
206 codec_base
->decode_video
= decode
;
207 codec_base
->encode_video
= encode
;
208 codec_base
->decode_audio
= 0;
209 codec_base
->encode_audio
= 0;
210 codec_base
->reads_colormodel
= reads_colormodel
;
211 codec_base
->fourcc
= QUICKTIME_YUV420
;
212 codec_base
->title
= "YUV 4:2:0 Planar";
213 codec_base
->desc
= "YUV 4:2:0 Planar";