allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / qth264.c
1 #include "libavcodec/avcodec.h"
2 #include "colormodels.h"
3 #include "funcprotos.h"
4 #include "qtffmpeg.h"
5 #include "quicktime.h"
6 #include "workarounds.h"
7 #include "x264.h"
8
9 #include <string.h>
10
11 // This generates our own header using fixed parameters
12 //#define MANUAL_HEADER
13
14
15 typedef struct
16 {
17 // Encoder side
18         x264_t *encoder[FIELDS];
19         x264_picture_t *pic[FIELDS];
20         x264_param_t param;
21
22         int encode_initialized[FIELDS];
23
24 // Temporary storage for color conversions
25         char *temp_frame;
26 // Storage of compressed data
27         unsigned char *work_buffer;
28 // Amount of data in work_buffer
29         int buffer_size;
30         int total_fields;
31 // Set by flush
32         int flushing;
33
34 // Decoder side
35         quicktime_ffmpeg_t *decoder;
36
37 } quicktime_h264_codec_t;
38
39 static pthread_mutex_t h264_lock = PTHREAD_MUTEX_INITIALIZER;
40
41
42 // Direct copy routines
43 int quicktime_h264_is_key(unsigned char *data, long size, char *codec_id)
44 {
45         return 0;
46 }
47
48
49 static void delete_codec(quicktime_video_map_t *vtrack)
50 {
51         int i;
52         quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
53
54         for(i = 0; i < codec->total_fields; i++) {
55                 if( !codec->encode_initialized[i]) continue;
56                 pthread_mutex_lock(&h264_lock);
57                 if(codec->pic[i]) {
58                         x264_picture_clean(codec->pic[i]);
59                         free(codec->pic[i]);
60                 }
61                 if(codec->encoder[i]) {
62                         x264_encoder_close(codec->encoder[i]);
63                 }
64                 pthread_mutex_unlock(&h264_lock);
65         }
66
67         if(codec->temp_frame) free(codec->temp_frame);
68         if(codec->work_buffer) free(codec->work_buffer);
69         if(codec->decoder) quicktime_delete_ffmpeg(codec->decoder);
70         free(codec);
71 }
72
73
74
75 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
76 {
77 //      int64_t offset = quicktime_position(file);
78         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
79         quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
80         quicktime_trak_t *trak = vtrack->track;
81         int width = quicktime_video_width(file, track);
82         int height = quicktime_video_height(file, track);
83         int w_2 = quicktime_quantize2(width);
84 // ffmpeg interprets the codec height as the presentation height
85         int h_2 = quicktime_quantize2(height);
86         int i;
87         int result = -1;
88         int is_keyframe = 0;
89         int frame_number = vtrack->current_position / codec->total_fields;
90         int current_field = vtrack->current_position % codec->total_fields;
91         quicktime_atom_t chunk_atom;
92         unsigned char header[1024];
93         int header_size = 0;
94         int got_pps = 0;
95         int got_sps = 0;
96         quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
97
98         pthread_mutex_lock(&h264_lock);
99
100         if(!codec->encode_initialized[current_field])
101         {
102                 codec->encode_initialized[current_field] = 1;
103                 codec->param.i_width = w_2;
104                 codec->param.i_height = h_2;
105                 codec->param.i_fps_num = quicktime_frame_rate_n(file, track);
106                 codec->param.i_fps_den = quicktime_frame_rate_d(file, track);
107
108 // Reset quantizer if fixed bitrate
109                 x264_param_t default_params;
110                 x264_param_default(&default_params);
111                 if(codec->param.rc.i_qp_constant)
112                 {
113                         codec->param.rc.i_qp_constant = default_params.rc.i_qp_constant;
114                         codec->param.rc.i_qp_min = default_params.rc.i_qp_min;
115                         codec->param.rc.i_qp_max = default_params.rc.i_qp_max;
116                 }
117
118                 if(file->cpus > 1)
119                 {
120                         codec->param.i_threads = file->cpus;
121                 }
122
123                 codec->encoder[current_field] = x264_encoder_open(&codec->param);
124                 codec->pic[current_field] = calloc(1, sizeof(x264_picture_t));
125                 x264_picture_init(codec->pic[current_field]);
126 //printf("encode 1 %d %d\n", codec->param.i_width, codec->param.i_height);
127                 x264_picture_alloc(codec->pic[current_field], X264_CSP_I420,
128                         codec->param.i_width, codec->param.i_height);
129         }
130
131         x264_picture_t *pic = codec->pic[current_field];
132         pic->i_type = X264_TYPE_AUTO;
133         pic->i_qpplus1 = X264_QP_AUTO;
134         pic->i_pts = frame_number;
135
136         codec->buffer_size = 0;
137         int allocation = w_2 * h_2 * 3 + 100;
138         if( !codec->work_buffer ) {
139                 codec->work_buffer = calloc(1, allocation);
140         }
141
142         x264_picture_t pic_out;
143         x264_nal_t *nals;
144         int nnal = 0;
145         x264_t *h = codec->encoder[current_field];
146
147         if( !codec->flushing ) {
148                 if( !row_pointers ) {
149                         bzero(pic->img.plane[0], w_2 * h_2);
150                         bzero(pic->img.plane[1], w_2 * h_2 / 4);
151                         bzero(pic->img.plane[2], w_2 * h_2 / 4);
152                 }
153                 else if( file->color_model == BC_YUV420P ) {
154                         memcpy(pic->img.plane[0], row_pointers[0], w_2 * h_2);
155                         memcpy(pic->img.plane[1], row_pointers[1], w_2 * h_2 / 4);
156                         memcpy(pic->img.plane[2], row_pointers[2], w_2 * h_2 / 4);
157                 }
158                 else {
159 //printf("encode 2 %p %p %p\n", pic->img.plane[0], pic->img.plane[1], pic->img.plane[2]);
160                         cmodel_transfer(0, row_pointers,
161                                 pic->img.plane[0], pic->img.plane[1], pic->img.plane[2],
162                                 row_pointers[0], row_pointers[1], row_pointers[2],
163                                 0, 0, width, height,  0, 0, width, height,
164                                 file->color_model, BC_YUV420P,
165                                 0, width, pic->img.i_stride[0]);
166                 }
167
168                 result = x264_encoder_encode(h, &nals, &nnal, pic, &pic_out);
169                 if( result < 0 )
170                         printf("frame_num %d:  nals=%d, ret=%d\n", frame_number, nnal, result);
171         }
172         else if( x264_encoder_delayed_frames(h) > 0 ) {
173                 result = x264_encoder_encode(h, &nals, &nnal, 0, &pic_out);
174                 if( result < 0 )
175                         printf("flushing %d:  nals=%d, ret=%d\n", frame_number, nnal, result);
176         }
177 //printf("encode %d nnal=%d\n", __LINE__, nnal);
178
179         for( i = 0; i < nnal; ++i ) {
180                 int size = nals[i].i_payload;
181 //printf("encode %d size=%d\n", __LINE__, size);
182                 if(size + codec->buffer_size > allocation) {
183                         printf("qth264.c %d: overflow size=%d allocation=%d\n",
184                                 __LINE__, size, allocation);
185                         break;
186                 }
187                 unsigned char *ptr = codec->work_buffer + codec->buffer_size;
188                 memcpy(ptr, nals[i].p_payload, size);
189                 codec->buffer_size += size;
190                 if( avcc->data_size ) continue;
191 // Snoop NAL for avc
192                 ptr += 4;  size -= 4;
193 // Synthesize header.
194 // Hopefully all the parameter set NAL's are present in the first frame.
195                 if( !header_size ) {
196                         header[header_size++] = 0x01;
197                         header[header_size++] = 0x4d;
198                         header[header_size++] = 0x40;
199                         header[header_size++] = 0x1f;
200                         header[header_size++] = 0xff;
201                         header[header_size++] = 0xe1;
202                 }
203
204                 int nal_type = (*ptr & 0x1f);
205 // Picture parameter or sequence parameter set
206                 switch( nal_type ) {
207                 case 0x07:
208                         if( got_sps ) continue;
209                         got_sps = 1;
210                         break;
211                 case 0x08:
212                         if( got_pps ) continue;
213                         got_pps = 1;
214                         header[header_size++] = 0x1; // Number of sps nal's.
215                         break;
216                 default:
217                         continue;
218                 }
219
220                 header[header_size++] = size >> 8;
221                 header[header_size++] = size;
222                 memcpy(&header[header_size], ptr, size);
223                 header_size += size;
224                 if( !got_sps || !got_pps ) continue;
225 // printf("encode %d\n", __LINE__);
226 // { int j; for(j = 0; j < header_size; j++) printf("%02x ", header[j]); }
227 // printf("\n");
228 // Write header
229                 quicktime_set_avcc_header(avcc, header, header_size);
230         }
231
232         pthread_mutex_unlock(&h264_lock);
233
234         if( codec->buffer_size > 0 ) {
235                 if(pic_out.i_type == X264_TYPE_IDR ||
236                         pic_out.i_type == X264_TYPE_I) {
237                         is_keyframe = 1;
238                 }
239
240                 quicktime_write_chunk_header(file, trak, &chunk_atom);
241                 result = !quicktime_write_data(file,
242                         (char*)codec->work_buffer,
243                         codec->buffer_size);
244                 quicktime_write_chunk_footer(file, trak,
245                         vtrack->current_chunk, &chunk_atom, 1);
246
247                 if(is_keyframe) {
248                         quicktime_insert_keyframe(file,
249                                 vtrack->current_position,
250                                 track);
251                 }
252
253                 vtrack->current_chunk++;
254         }
255         return result >= 0 ? 0 : -1;
256 }
257
258
259
260
261 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
262 {
263         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
264         quicktime_trak_t *trak = vtrack->track;
265         quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
266         quicktime_stsd_table_t *stsd_table = &trak->mdia.minf.stbl.stsd.table[0];
267         int width = trak->tkhd.track_width;
268         int height = trak->tkhd.track_height;
269
270         if(!codec->decoder)
271                 codec->decoder = quicktime_new_ffmpeg(file->cpus,
272                         codec->total_fields, CODEC_ID_H264, width, height, stsd_table);
273         return !codec->decoder ? 1 :
274                 quicktime_ffmpeg_decode(codec->decoder, file, row_pointers, track); 
275 }
276
277 static void flush(quicktime_t *file, int track)
278 {
279         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
280         quicktime_trak_t *trak = vtrack->track;
281         quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
282 //      trak->mdia.minf.stbl.stsd.table[0].version = 1;
283 //      trak->mdia.minf.stbl.stsd.table[0].revision = 1;
284         quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc;
285         if( !avcc->data_size )
286                 encode(file, 0, track);
287         codec->flushing = 1;
288         while( !encode(file, 0, track) );
289 }
290
291
292
293 static int reads_colormodel(quicktime_t *file,
294                 int colormodel,
295                 int track)
296 {
297         return (colormodel == BC_YUV420P);
298 }
299
300 static int writes_colormodel(quicktime_t *file,
301                 int colormodel,
302                 int track)
303 {
304         return (colormodel == BC_YUV420P);
305 }
306
307 static int set_parameter(quicktime_t *file,
308                 int track,
309                 char *key,
310                 void *value)
311 {
312         quicktime_video_map_t *vtrack = &(file->vtracks[track]);
313         char *compressor = quicktime_compressor(vtrack->track);
314
315         if(quicktime_match_32(compressor, QUICKTIME_H264) ||
316                 quicktime_match_32(compressor, QUICKTIME_HV64))
317         {
318                 quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
319                 if(!strcasecmp(key, "h264_bitrate"))
320                 {
321                         if(quicktime_match_32(compressor, QUICKTIME_H264))
322                                 codec->param.rc.i_bitrate = *(int*)value;
323                         else
324                                 codec->param.rc.i_bitrate = *(int*)value / 2;
325                 }
326                 else
327                 if(!strcasecmp(key, "h264_quantizer"))
328                 {
329                         codec->param.rc.i_qp_constant =
330                                 codec->param.rc.i_qp_min =
331                                 codec->param.rc.i_qp_max = *(int*)value;
332                 }
333                 else
334                 if(!strcasecmp(key, "h264_fix_bitrate"))
335                 {
336                         codec->param.rc.i_qp_constant = (*(int*)value) / 1000;
337                 }
338         }
339         return 0;
340 }
341
342 static quicktime_h264_codec_t* init_common(quicktime_video_map_t *vtrack,
343         char *compressor,
344         char *title,
345         char *description)
346 {
347         quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
348         quicktime_h264_codec_t *codec;
349
350         codec_base->priv = calloc(1, sizeof(quicktime_h264_codec_t));
351         codec_base->delete_vcodec = delete_codec;
352         codec_base->decode_video = decode;
353         codec_base->encode_video = encode;
354         codec_base->flush = flush;
355         codec_base->reads_colormodel = reads_colormodel;
356         codec_base->writes_colormodel = writes_colormodel;
357         codec_base->set_parameter = set_parameter;
358         codec_base->fourcc = compressor;
359         codec_base->title = title;
360         codec_base->desc = description;
361
362
363         codec = (quicktime_h264_codec_t*)codec_base->priv;
364         x264_param_default(&codec->param);
365         codec->param.rc.i_rc_method = X264_RC_CQP;
366 //      codec->param.i_log_level = 99;
367         return codec;
368 }
369
370
371 void quicktime_init_codec_h264(quicktime_video_map_t *vtrack)
372 {
373     quicktime_h264_codec_t *result = init_common(vtrack,
374         QUICKTIME_H264,
375         "H.264",
376         "H.264");
377         result->total_fields = 1;
378 }
379
380
381 // field based H.264
382 void quicktime_init_codec_hv64(quicktime_video_map_t *vtrack)
383 {
384         quicktime_h264_codec_t *result = init_common(vtrack,
385                 QUICKTIME_HV64,
386                 "Dual H.264",
387                 "H.264 with two streams alternating every other frame.  (Not standardized)");
388         result->total_fields = 2;
389 }
390
391
392
393