1 #include "colormodels.h"
2 #include "funcprotos.h"
8 // FFMPEG front end for quicktime.
17 int ffmpeg_initialized
= 0;
18 pthread_mutex_t ffmpeg_lock
= PTHREAD_MUTEX_INITIALIZER
;
25 quicktime_ffmpeg_t
* quicktime_new_ffmpeg(int cpus
,
30 quicktime_stsd_table_t
*stsd_table
)
32 quicktime_ffmpeg_t
*ptr
= calloc(1, sizeof(quicktime_ffmpeg_t
));
33 quicktime_esds_t
*esds
= &stsd_table
->esds
;
34 quicktime_avcc_t
*avcc
= &stsd_table
->avcc
;
40 ptr
->ffmpeg_id
= ffmpeg_id
;
41 //printf("quicktime_new_ffmpeg 1 %d\n", ptr->ffmpeg_id);
42 if(ffmpeg_id
== CODEC_ID_SVQ1
)
44 ptr
->width_i
= quicktime_quantize32(ptr
->width
);
45 ptr
->height_i
= quicktime_quantize32(ptr
->height
);
49 ptr
->width_i
= quicktime_quantize16(ptr
->width
);
50 ptr
->height_i
= quicktime_quantize16(ptr
->height
);
53 pthread_mutex_lock(&ffmpeg_lock
);
54 if(!ffmpeg_initialized
)
56 ffmpeg_initialized
= 1;
58 avcodec_register_all();
61 for(i
= 0; i
< fields
; i
++)
63 ptr
->decoder
[i
] = avcodec_find_decoder(ptr
->ffmpeg_id
);
66 printf("quicktime_new_ffmpeg: avcodec_find_decoder returned NULL.\n");
67 quicktime_delete_ffmpeg(ptr
);
71 AVCodecContext
*context
= ptr
->decoder_context
[i
] = avcodec_alloc_context();
72 static char fake_data
[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
73 context
->width
= ptr
->width_i
;
74 context
->height
= ptr
->height_i
;
75 // context->width = w;
76 // context->height = h;
77 context
->extradata
= fake_data
;
78 context
->extradata_size
= 0;
79 if(esds
->mpeg4_header
&& esds
->mpeg4_header_size
)
81 context
->extradata
= esds
->mpeg4_header
;
82 context
->extradata_size
= esds
->mpeg4_header_size
;
84 if(avcc
->data
&& avcc
->data_size
)
86 context
->extradata
= avcc
->data
;
87 context
->extradata_size
= avcc
->data_size
;
91 avcodec_thread_init(context
, cpus
);
92 context
->thread_count
= cpus
;
94 if(avcodec_open(context
,
97 printf("quicktime_new_ffmpeg: avcodec_open failed.\n");
98 quicktime_delete_ffmpeg(ptr
);
100 ptr
->last_frame
[i
] = -1;
102 pthread_mutex_unlock(&ffmpeg_lock
);
109 void quicktime_delete_ffmpeg(quicktime_ffmpeg_t
*ptr
)
114 pthread_mutex_lock(&ffmpeg_lock
);
115 for(i
= 0; i
< ptr
->fields
; i
++)
117 if(ptr
->decoder_context
[i
])
119 avcodec_close(ptr
->decoder_context
[i
]);
120 free(ptr
->decoder_context
[i
]);
123 pthread_mutex_unlock(&ffmpeg_lock
);
127 if(ptr
->temp_frame
) free(ptr
->temp_frame
);
128 if(ptr
->work_buffer
) free(ptr
->work_buffer
);
136 static int decode_wrapper(quicktime_t
*file
,
137 quicktime_video_map_t
*vtrack
,
138 quicktime_ffmpeg_t
*ffmpeg
,
147 int header_bytes
= 0;
148 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
149 quicktime_trak_t
*trak
= vtrack
->track
;
150 quicktime_stsd_table_t
*stsd_table
= &trak
->mdia
.minf
.stbl
.stsd
.table
[0];
152 //printf("decode_wrapper %d\n", frame_number);
153 quicktime_set_video_position(file
, frame_number
, track
);
155 bytes
= quicktime_frame_size(file
, frame_number
, track
);
156 if(frame_number
== 0)
158 header_bytes
= stsd_table
->esds
.mpeg4_header_size
;
161 if(!ffmpeg
->work_buffer
|| ffmpeg
->buffer_size
< bytes
+ header_bytes
)
163 if(ffmpeg
->work_buffer
) free(ffmpeg
->work_buffer
);
164 ffmpeg
->buffer_size
= bytes
+ header_bytes
;
165 ffmpeg
->work_buffer
= calloc(1, ffmpeg
->buffer_size
+ 100);
169 memcpy(ffmpeg
->work_buffer
, stsd_table
->esds
.mpeg4_header
, header_bytes
);
171 if(!quicktime_read_data(file
,
172 ffmpeg
->work_buffer
+ header_bytes
,
181 // No way to determine if there was an error based on nonzero status.
182 // Need to test row pointers to determine if an error occurred.
184 ffmpeg
->decoder_context
[current_field
]->skip_frame
= AVDISCARD_NONREF
/* AVDISCARD_BIDIR */;
186 ffmpeg
->decoder_context
[current_field
]->skip_frame
= AVDISCARD_DEFAULT
;
187 result
= avcodec_decode_video(ffmpeg
->decoder_context
[current_field
],
188 &ffmpeg
->picture
[current_field
],
191 bytes
+ header_bytes
);
195 if(ffmpeg
->picture
[current_field
].data
[0])
201 // ffmpeg can't recover if the first frame errored out, like in a direct copy
214 // Get amount chroma planes are downsampled from luma plane.
215 // Used for copying planes into cache.
216 static int get_chroma_factor(quicktime_ffmpeg_t
*ffmpeg
, int current_field
)
218 switch(ffmpeg
->decoder_context
[current_field
]->pix_fmt
)
220 case PIX_FMT_YUV420P
:
226 case PIX_FMT_YUV422P
:
229 case PIX_FMT_YUV410P
:
234 "get_chroma_factor: unrecognized color model %d\n",
235 ffmpeg
->decoder_context
[current_field
]->pix_fmt
);
241 int quicktime_ffmpeg_decode(quicktime_ffmpeg_t
*ffmpeg
,
243 unsigned char **row_pointers
,
246 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
247 quicktime_trak_t
*trak
= vtrack
->track
;
248 int current_field
= vtrack
->current_position
% ffmpeg
->fields
;
251 int seeking_done
= 0;
255 result
= quicktime_get_frame(vtrack
->frame_cache
,
256 vtrack
->current_position
,
257 &ffmpeg
->picture
[current_field
].data
[0],
258 &ffmpeg
->picture
[current_field
].data
[1],
259 &ffmpeg
->picture
[current_field
].data
[2]);
265 // Codecs which work without locking:
268 // pthread_mutex_lock(&ffmpeg_lock);
270 //printf("quicktime_ffmpeg_decode 1 %d\n", ffmpeg->last_frame[current_field]);
272 if(ffmpeg
->last_frame
[current_field
] == -1 &&
273 ffmpeg
->ffmpeg_id
!= CODEC_ID_H264
)
275 int current_frame
= vtrack
->current_position
;
276 // For certain codecs,
277 // must decode frame with stream header first but only the first frame in the
278 // field sequence has a stream header.
279 result
= decode_wrapper(file
,
286 // Reset position because decode wrapper set it
287 quicktime_set_video_position(file
, current_frame
, track
);
288 ffmpeg
->last_frame
[current_field
] = current_field
;
293 // Seeking requires keyframes
294 if(quicktime_has_keyframes(file
, track
) &&
296 vtrack
->current_position
!= ffmpeg
->last_frame
[current_field
] + ffmpeg
->fields
&&
297 // Same frame requested twice
298 vtrack
->current_position
!= ffmpeg
->last_frame
[current_field
])
302 int frame2
= vtrack
->current_position
;
303 int current_frame
= frame2
;
306 // If an interleaved codec, the opposite field would have been decoded in the previous
308 if(!quicktime_has_frame(vtrack
->frame_cache
, vtrack
->current_position
+ 1))
309 quicktime_reset_cache(vtrack
->frame_cache
);
311 // Get first keyframe of same field
312 frame1
= current_frame
;
315 frame1
= quicktime_get_keyframe_before(file
,
318 }while(frame1
> 0 && (frame1
% ffmpeg
->fields
) != current_field
);
319 //printf("quicktime_ffmpeg_decode 1 %d\n", frame1);
321 // For MPEG-4, get another keyframe before first keyframe.
322 // The Sanyo tends to glitch with only 1 keyframe.
323 // Not enough memory.
324 if( 0 /* frame1 > 0 && ffmpeg->ffmpeg_id == CODEC_ID_MPEG4 */)
328 frame1
= quicktime_get_keyframe_before(file
,
331 }while(frame1
> 0 && (frame1
& ffmpeg
->fields
) != current_field
);
332 //printf("quicktime_ffmpeg_decode 2 %d\n", frame1);
335 // Keyframe is before last decoded frame and current frame is after last decoded
336 // frame, so instead of rerendering from the last keyframe we can rerender from
337 // the last decoded frame.
338 if(frame1
< ffmpeg
->last_frame
[current_field
] &&
339 frame2
> ffmpeg
->last_frame
[current_field
])
341 frame1
= ffmpeg
->last_frame
[current_field
] + ffmpeg
->fields
;
345 first_frame
= frame1
;
347 //printf("quicktime_ffmpeg_decode 2 %d\n", ffmpeg->last_frame[current_field]);
348 while(frame1
<= frame2
)
350 result
= decode_wrapper(file
,
356 // Don't drop if we want to cache it
357 0 /* (frame1 < frame2) */);
359 if(ffmpeg
->picture
[current_field
].data
[0] &&
360 // FFmpeg seems to glitch out if we include the first frame.
361 frame1
> first_frame
)
363 int y_size
= ffmpeg
->picture
[current_field
].linesize
[0] * ffmpeg
->height_i
;
364 int u_size
= y_size
/ get_chroma_factor(ffmpeg
, current_field
);
365 int v_size
= y_size
/ get_chroma_factor(ffmpeg
, current_field
);
366 quicktime_put_frame(vtrack
->frame_cache
,
368 ffmpeg
->picture
[current_field
].data
[0],
369 ffmpeg
->picture
[current_field
].data
[1],
370 ffmpeg
->picture
[current_field
].data
[2],
377 // may need to do the same frame twice if it is the first I frame.
380 result
= decode_wrapper(file
,
389 frame1
+= ffmpeg
->fields
;
392 vtrack
->current_position
= frame2
;
396 // Not decoded in seeking process
398 // Same frame not requested
399 vtrack
->current_position
!= ffmpeg
->last_frame
[current_field
])
401 result
= decode_wrapper(file
,
404 vtrack
->current_position
,
410 // pthread_mutex_unlock(&ffmpeg_lock);
413 ffmpeg
->last_frame
[current_field
] = vtrack
->current_position
;
416 // Hopefully this setting will be left over if the cache was used.
417 switch(ffmpeg
->decoder_context
[current_field
]->pix_fmt
)
419 case PIX_FMT_YUV420P
:
420 input_cmodel
= BC_YUV420P
;
423 input_cmodel
= BC_YUV422
;
425 case PIX_FMT_YUV422P
:
426 input_cmodel
= BC_YUV422P
;
428 case PIX_FMT_YUV410P
:
429 input_cmodel
= BC_YUV9P
;
433 "quicktime_ffmpeg_decode: unrecognized color model %d\n",
434 ffmpeg
->decoder_context
[current_field
]->pix_fmt
);
435 input_cmodel
= BC_YUV420P
;
439 if(ffmpeg
->picture
[current_field
].data
[0])
441 unsigned char **input_rows
;
444 malloc(sizeof(unsigned char*) *
445 ffmpeg
->decoder_context
[current_field
]->height
);
448 for(i
= 0; i
< ffmpeg
->decoder_context
[current_field
]->height
; i
++)
449 input_rows
[i
] = ffmpeg
->picture
[current_field
].data
[0] +
451 ffmpeg
->decoder_context
[current_field
]->width
*
452 cmodel_calculate_pixelsize(input_cmodel
);
455 cmodel_transfer(row_pointers
, /* Leave NULL if non existent */
457 row_pointers
[0], /* Leave NULL if non existent */
460 ffmpeg
->picture
[current_field
].data
[0], /* Leave NULL if non existent */
461 ffmpeg
->picture
[current_field
].data
[1],
462 ffmpeg
->picture
[current_field
].data
[2],
463 file
->in_x
, /* Dimensions to capture from input frame */
467 0, /* Dimensions to project on output frame */
473 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
474 ffmpeg
->picture
[current_field
].linesize
[0], /* For planar use the luma rowspan */