1 /*****************************************************************************
2 * libavsmash_input.c
3 *****************************************************************************
4 * Copyright (C) 2011-2015 L-SMASH Works project
5 *
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
20
21 /* This file is available under an ISC license.
22 * However, when distributing its binary file, it will be under LGPL or GPL.
23 * Don't distribute it if its license is GPL. */
24
25 /* L-SMASH */
26 #include <lsmash.h> /* Demuxer */
27
28 /* Libav
29 * The binary file will be LGPLed or GPLed. */
30 #include <libavformat/avformat.h> /* Codec specific info importer */
31 #include <libavcodec/avcodec.h> /* Decoder */
32 #include <libswscale/swscale.h> /* Colorspace converter */
33 #include <libavresample/avresample.h> /* Audio resampler */
34 #include <libavutil/mathematics.h>
35
36 #include "lwinput.h"
37 #include "video_output.h"
38 #include "audio_output.h"
39
40 #include "../common/libavsmash.h"
41 #include "../common/libavsmash_video.h"
42 #include "../common/libavsmash_audio.h"
43
44 typedef struct
45 {
46 uint32_t media_timescale;
47 uint64_t skip_duration;
48 int64_t start_pts;
49 } libavsmash_video_info_handler_t;
50
51 typedef struct
52 {
53 uint32_t media_timescale;
54 int64_t start_pts;
55 } libavsmash_audio_info_handler_t;
56
57 typedef struct libavsmash_handler_tag
58 {
59 /* Global stuff */
60 UINT uType;
61 lsmash_root_t *root;
62 lsmash_file_parameters_t file_param;
63 lsmash_movie_parameters_t movie_param;
64 uint32_t number_of_tracks;
65 AVFormatContext *format_ctx;
66 int threads;
67 /* Video stuff */
68 libavsmash_video_info_handler_t vih;
69 libavsmash_video_decode_handler_t *vdhp;
70 libavsmash_video_output_handler_t *vohp;
71 /* Audio stuff */
72 libavsmash_audio_info_handler_t aih;
73 libavsmash_audio_decode_handler_t *adhp;
74 libavsmash_audio_output_handler_t *aohp;
75 int64_t av_gap;
76 int av_sync;
77 } libavsmash_handler_t;
78
79 /* Deallocate the handler of this plugin. */
free_handler(libavsmash_handler_t ** hpp)80 static void free_handler
81 (
82 libavsmash_handler_t **hpp
83 )
84 {
85 if( !hpp || !*hpp )
86 return;
87 libavsmash_handler_t *hp = *hpp;
88 libavsmash_video_free_decode_handler( hp->vdhp );
89 libavsmash_video_free_output_handler( hp->vohp );
90 libavsmash_audio_free_decode_handler( hp->adhp );
91 libavsmash_audio_free_output_handler( hp->aohp );
92 lw_freep( hpp );
93 }
94
95 /* Allocate the handler of this plugin. */
alloc_handler(void)96 static libavsmash_handler_t *alloc_handler
97 (
98 void
99 )
100 {
101 libavsmash_handler_t *hp = lw_malloc_zero( sizeof(libavsmash_handler_t) );
102 if( !hp )
103 return NULL;
104 if( !(hp->vdhp = libavsmash_video_alloc_decode_handler())
105 || !(hp->vohp = libavsmash_video_alloc_output_handler())
106 || !(hp->adhp = libavsmash_audio_alloc_decode_handler())
107 || !(hp->aohp = libavsmash_audio_alloc_output_handler()) )
108 {
109 free_handler( &hp );
110 return NULL;
111 }
112 return hp;
113 }
114
get_first_track_of_type(lsmash_handler_t * h,uint32_t type)115 static int get_first_track_of_type( lsmash_handler_t *h, uint32_t type )
116 {
117 int ret;
118 lw_log_handler_t *lhp;
119 if( type == ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK )
120 {
121 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
122 lhp = libavsmash_video_get_log_handler( hp->vdhp );
123 libavsmash_video_set_root( hp->vdhp, hp->root );
124 ret = libavsmash_video_get_track( hp->vdhp, 0 );
125 }
126 else
127 {
128 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
129 lhp = libavsmash_audio_get_log_handler( hp->adhp );
130 libavsmash_audio_set_root( hp->adhp, hp->root );
131 ret = libavsmash_audio_get_track( hp->adhp, 0 );
132 }
133 lhp->level = LW_LOG_WARNING;
134 return ret;
135 }
136
get_ctd_shift(lsmash_root_t * root,uint32_t track_id,uint32_t * ctd_shift)137 static int get_ctd_shift
138 (
139 lsmash_root_t *root,
140 uint32_t track_id,
141 uint32_t *ctd_shift
142 )
143 {
144 if( lsmash_get_composition_to_decode_shift_from_media_timeline( root, track_id, ctd_shift ) )
145 {
146 DEBUG_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to get the timeline shift." );
147 return -1;
148 }
149 return 0;
150 }
151
get_empty_duration(lsmash_root_t * root,uint32_t track_id,uint32_t movie_timescale,uint32_t media_timescale)152 static uint64_t get_empty_duration
153 (
154 lsmash_root_t *root,
155 uint32_t track_id,
156 uint32_t movie_timescale,
157 uint32_t media_timescale
158 )
159 {
160 /* Consider empty duration if the first edit is an empty edit. */
161 lsmash_edit_t edit;
162 if( lsmash_get_explicit_timeline_map( root, track_id, 1, &edit ) )
163 return 0;
164 if( edit.duration && edit.start_time == ISOM_EDIT_MODE_EMPTY )
165 return av_rescale_q( edit.duration,
166 (AVRational){ 1, movie_timescale },
167 (AVRational){ 1, media_timescale } );
168 return 0;
169 }
170
get_start_time(lsmash_root_t * root,uint32_t track_id)171 static int64_t get_start_time
172 (
173 lsmash_root_t *root,
174 uint32_t track_id
175 )
176 {
177 /* Consider start time of this media if any non-empty edit is present. */
178 uint32_t edit_count = lsmash_count_explicit_timeline_map( root, track_id );
179 for( uint32_t edit_number = 1; edit_number <= edit_count; edit_number++ )
180 {
181 lsmash_edit_t edit;
182 if( lsmash_get_explicit_timeline_map( root, track_id, edit_number, &edit ) )
183 return 0;
184 if( edit.duration == 0 )
185 return 0; /* no edits */
186 if( edit.start_time >= 0 )
187 return edit.start_time;
188 }
189 return 0;
190 }
191
prepare_video_decoding(lsmash_handler_t * h,video_option_t * opt)192 static int prepare_video_decoding( lsmash_handler_t *h, video_option_t *opt )
193 {
194 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
195 libavsmash_video_decode_handler_t *vdhp = hp->vdhp;
196 /* Initialize the video decoder configuration. */
197 if( libavsmash_video_initialize_decoder_configuration( vdhp, hp->format_ctx, hp->threads ) < 0 )
198 {
199 DEBUG_VIDEO_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to initialize the decoder configuration." );
200 return -1;
201 }
202 AVCodecContext *ctx = libavsmash_video_get_codec_context( vdhp );
203 if( !ctx )
204 return 0;
205 /* Set up video rendering. */
206 libavsmash_video_output_handler_t *vohp = hp->vohp;
207 int max_width = libavsmash_video_get_max_width ( vdhp );
208 int max_height = libavsmash_video_get_max_height( vdhp );
209 if( au_setup_video_rendering( vohp, opt, &h->video_format, max_width, max_height, ctx->pix_fmt ) < 0 )
210 return -1;
211 /* Set up timestamp info. */
212 int64_t fps_num = 25;
213 int64_t fps_den = 1;
214 libavsmash_video_setup_timestamp_info( vdhp, vohp, &fps_num, &fps_den );
215 if( libavsmash_video_get_error( vdhp ) )
216 {
217 DEBUG_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to get the minimum CTS of video stream." );
218 return -1;
219 }
220 /* Create keyframe list.
221 * This requires frame output order, therefore, shall be called after libavsmash_video_setup_timestamp_info(). */
222 if( libavsmash_video_create_keyframe_list( vdhp ) < 0 )
223 {
224 DEBUG_VIDEO_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to create keyframe list." );
225 return -1;
226 }
227 #ifndef DEBUG_VIDEO
228 lw_log_handler_t *lhp = libavsmash_video_get_log_handler( vdhp );
229 lhp->level = LW_LOG_FATAL;
230 #endif
231 /* Find the first valid video frame. */
232 if( libavsmash_video_find_first_valid_frame( vdhp ) < 0 )
233 return -1;
234 /* Setup the reader specific info. */
235 uint32_t media_timescale = libavsmash_video_get_media_timescale( vdhp );
236 if( hp->av_sync )
237 {
238 uint32_t track_id = libavsmash_video_get_track_id( vdhp );
239 uint32_t ctd_shift;
240 if( get_ctd_shift( hp->root, track_id, &ctd_shift ) < 0 )
241 return -1;
242 uint64_t min_cts = libavsmash_video_get_min_cts( vdhp );
243 uint32_t movie_timescale = hp->movie_param.timescale;
244 hp->vih.start_pts = min_cts + ctd_shift
245 + get_empty_duration( hp->root, track_id, movie_timescale, media_timescale );
246 hp->vih.skip_duration = ctd_shift + get_start_time( hp->root, track_id );
247 }
248 hp->vih.media_timescale = media_timescale;
249 h->framerate_num = (int)fps_num;
250 h->framerate_den = (int)fps_den;
251 h->video_sample_count = vohp->frame_count;
252 /* Force seeking at the first reading. */
253 libavsmash_video_force_seek( vdhp );
254 return 0;
255 }
256
prepare_audio_decoding(lsmash_handler_t * h,audio_option_t * opt)257 static int prepare_audio_decoding( lsmash_handler_t *h, audio_option_t *opt )
258 {
259 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
260 libavsmash_audio_decode_handler_t *adhp = hp->adhp;
261 /* Initialize the audio decoder configuration. */
262 if( libavsmash_audio_initialize_decoder_configuration( adhp, hp->format_ctx, hp->threads ) < 0 )
263 {
264 DEBUG_VIDEO_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to initialize the decoder configuration." );
265 return -1;
266 }
267 AVCodecContext *ctx = libavsmash_audio_get_codec_context( adhp );
268 if( !ctx )
269 return 0;
270 libavsmash_audio_output_handler_t *aohp = hp->aohp;
271 aohp->output_channel_layout = libavsmash_audio_get_best_used_channel_layout ( adhp );
272 aohp->output_sample_format = libavsmash_audio_get_best_used_sample_format ( adhp );
273 aohp->output_sample_rate = libavsmash_audio_get_best_used_sample_rate ( adhp );
274 aohp->output_bits_per_sample = libavsmash_audio_get_best_used_bits_per_sample( adhp );
275 /* */
276 #ifndef DEBUG_AUDIO
277 lw_log_handler_t *lhp = libavsmash_audio_get_log_handler( adhp );
278 lhp->level = LW_LOG_FATAL;
279 #endif
280 if( au_setup_audio_rendering( aohp, ctx, opt, &h->audio_format.Format ) < 0 )
281 return -1;
282 /* Setup the reader specific info.
283 * Note that this settings affects with the number of output PCM samples, therefore do before its counting and A/V sync settings. */
284 uint32_t media_timescale = libavsmash_audio_get_media_timescale( adhp );
285 uint64_t start_time = 0;
286 if( hp->av_sync )
287 {
288 uint64_t min_cts = libavsmash_audio_get_min_cts( adhp );
289 if( min_cts == UINT64_MAX )
290 {
291 DEBUG_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "Failed to get the minimum CTS of audio stream." );
292 return -1;
293 }
294 uint32_t track_id = libavsmash_audio_get_track_id( adhp );
295 uint32_t ctd_shift;
296 if( get_ctd_shift( hp->root, track_id, &ctd_shift ) < 0 )
297 return -1;
298 uint32_t movie_timescale = hp->movie_param.timescale;
299 hp->aih.start_pts = min_cts + ctd_shift
300 + get_empty_duration( hp->root, track_id, movie_timescale, media_timescale );
301 start_time = ctd_shift + get_start_time( hp->root, track_id );
302 }
303 hp->aih.media_timescale = media_timescale;
304 /* Count the number of PCM audio samples.
305 * TODO: Give start time before calling libavsmash_audio_count_overall_pcm_samples() and remove the 3rd argument. */
306 h->audio_pcm_sample_count = libavsmash_audio_count_overall_pcm_samples( adhp, aohp->output_sample_rate, start_time );
307 if( h->audio_pcm_sample_count == 0 )
308 {
309 DEBUG_AUDIO_MESSAGE_BOX_DESKTOP( MB_ICONERROR | MB_OK, "No valid audio frame." );
310 return -1;
311 }
312 if( hp->av_sync && libavsmash_video_get_track_id( hp->vdhp ) )
313 {
314 AVRational audio_sample_base = (AVRational){ 1, aohp->output_sample_rate };
315 hp->av_gap = av_rescale_q( hp->aih.start_pts,
316 (AVRational){ 1, hp->aih.media_timescale }, audio_sample_base )
317 - av_rescale_q( hp->vih.start_pts - hp->vih.skip_duration,
318 (AVRational){ 1, hp->vih.media_timescale }, audio_sample_base );
319 h->audio_pcm_sample_count += hp->av_gap;
320 uint32_t media_timescale = libavsmash_audio_get_media_timescale( adhp );
321 hp->aohp->skip_decoded_samples = av_rescale( start_time, aohp->output_sample_rate, media_timescale );
322 libavsmash_audio_apply_delay( adhp, hp->av_gap );
323 }
324 /* Force seeking at the first reading. */
325 libavsmash_audio_force_seek( adhp );
326 return 0;
327 }
328
open_file(char * file_name,reader_option_t * opt)329 static void *open_file( char *file_name, reader_option_t *opt )
330 {
331 libavsmash_handler_t *hp = alloc_handler();
332 if( !hp )
333 return NULL;
334 /* Set up the log handlers. */
335 hp->uType = MB_ICONERROR | MB_OK;
336 lw_log_handler_t *vlhp = libavsmash_video_get_log_handler( hp->vdhp );
337 lw_log_handler_t *alhp = libavsmash_audio_get_log_handler( hp->adhp );
338 vlhp->priv = &hp->uType;
339 vlhp->level = LW_LOG_QUIET;
340 vlhp->show_log = au_message_box_desktop;
341 *alhp = *vlhp;
342 /* Open file. */
343 hp->root = libavsmash_open_file( &hp->format_ctx, file_name, &hp->file_param, &hp->movie_param, vlhp );
344 if( !hp->root )
345 {
346 free_handler( &hp );
347 return NULL;
348 }
349 hp->number_of_tracks = hp->movie_param.number_of_tracks;
350 hp->threads = opt->threads;
351 hp->av_sync = opt->av_sync;
352 libavsmash_video_set_preferred_decoder_names( hp->vdhp, opt->preferred_decoder_names );
353 libavsmash_audio_set_preferred_decoder_names( hp->adhp, opt->preferred_decoder_names );
354 *alhp = *vlhp;
355 return hp;
356 }
357
get_first_video_track(lsmash_handler_t * h,video_option_t * opt)358 static int get_first_video_track( lsmash_handler_t *h, video_option_t *opt )
359 {
360 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
361 if( get_first_track_of_type( h, ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK ) != 0 )
362 {
363 uint32_t track_id = libavsmash_video_get_track_id( hp->vdhp );
364 lsmash_destruct_timeline( hp->root, track_id );
365 libavsmash_video_close_codec_context( hp->vdhp );
366 return -1;
367 }
368 /* Set video options. */
369 libavsmash_video_decode_handler_t *vdhp = hp->vdhp;
370 libavsmash_video_output_handler_t *vohp = hp->vohp;
371 libavsmash_video_set_seek_mode ( vdhp, opt->seek_mode );
372 libavsmash_video_set_forward_seek_threshold( vdhp, opt->forward_seek_threshold );
373 vohp->vfr2cfr = opt->vfr2cfr.active;
374 vohp->cfr_num = opt->vfr2cfr.framerate_num;
375 vohp->cfr_den = opt->vfr2cfr.framerate_den;
376 /* TODO: Maybe, the number of output frames should be set up here. */
377 return prepare_video_decoding( h, opt );
378 }
379
get_first_audio_track(lsmash_handler_t * h,audio_option_t * opt)380 static int get_first_audio_track( lsmash_handler_t *h, audio_option_t *opt )
381 {
382 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
383 if( get_first_track_of_type( h, ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK ) != 0 )
384 {
385 uint32_t track_id = libavsmash_audio_get_track_id( hp->adhp );
386 lsmash_destruct_timeline( hp->root, track_id );
387 libavsmash_audio_close_codec_context( hp->adhp );
388 return -1;
389 }
390 return prepare_audio_decoding( h, opt );
391 }
392
destroy_disposable(void * private_stuff)393 static void destroy_disposable( void *private_stuff )
394 {
395 libavsmash_handler_t *hp = (libavsmash_handler_t *)private_stuff;
396 lsmash_discard_boxes( hp->root );
397 }
398
read_video(lsmash_handler_t * h,int sample_number,void * buf)399 static int read_video( lsmash_handler_t *h, int sample_number, void *buf )
400 {
401 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
402 libavsmash_video_decode_handler_t *vdhp = hp->vdhp;
403 if( libavsmash_video_get_error( vdhp ) )
404 return 0;
405 libavsmash_video_output_handler_t *vohp = hp->vohp;
406 ++sample_number; /* For L-SMASH, sample_number is 1-origin. */
407 if( sample_number == 1 )
408 {
409 au_video_output_handler_t *au_vohp = (au_video_output_handler_t *)vohp->private_handler;
410 memcpy( buf, au_vohp->back_ground, au_vohp->output_frame_size );
411 }
412 int ret = libavsmash_video_get_frame( vdhp, vohp, sample_number );
413 if( ret != 0 && !(ret == 1 && sample_number == 1) )
414 /* Skip writing frame data into AviUtl's frame buffer.
415 * Apparently, AviUtl clears the frame buffer at the first frame.
416 * Therefore, don't skip in that case. */
417 return 0;
418 AVFrame *av_frame = libavsmash_video_get_frame_buffer( vdhp );
419 return convert_colorspace( vohp, av_frame, buf );
420 }
421
read_audio(lsmash_handler_t * h,int start,int wanted_length,void * buf)422 static int read_audio( lsmash_handler_t *h, int start, int wanted_length, void *buf )
423 {
424 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
425 return libavsmash_audio_get_pcm_samples( hp->adhp, hp->aohp, buf, start, wanted_length );
426 }
427
is_keyframe(lsmash_handler_t * h,int sample_number)428 static int is_keyframe( lsmash_handler_t *h, int sample_number )
429 {
430 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
431 return libavsmash_video_is_keyframe( hp->vdhp, hp->vohp, sample_number + 1 );
432 }
433
delay_audio(lsmash_handler_t * h,int * start,int wanted_length,int audio_delay)434 static int delay_audio( lsmash_handler_t *h, int *start, int wanted_length, int audio_delay )
435 {
436 /* Even if start become negative, its absolute value shall be equal to wanted_length or smaller. */
437 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
438 int end = *start + wanted_length;
439 audio_delay += hp->av_gap;
440 if( *start < audio_delay && end <= audio_delay )
441 {
442 libavsmash_audio_force_seek( hp->adhp ); /* Force seeking at the next access for valid audio frame. */
443 return 0;
444 }
445 *start -= audio_delay;
446 return 1;
447 }
448
video_cleanup(lsmash_handler_t * h)449 static void video_cleanup( lsmash_handler_t *h )
450 {
451 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->video_private;
452 if( !hp )
453 return;
454 /* Free and then set nullptr since other functions might reference the pointer later. */
455 libavsmash_video_free_decode_handler_ptr( &hp->vdhp );
456 libavsmash_video_free_output_handler_ptr( &hp->vohp );
457 }
458
audio_cleanup(lsmash_handler_t * h)459 static void audio_cleanup( lsmash_handler_t *h )
460 {
461 libavsmash_handler_t *hp = (libavsmash_handler_t *)h->audio_private;
462 if( !hp )
463 return;
464 /* Free and then set nullptr since other functions might reference the pointer later. */
465 libavsmash_audio_free_decode_handler_ptr( &hp->adhp );
466 libavsmash_audio_free_output_handler_ptr( &hp->aohp );
467 }
468
close_file(void * private_stuff)469 static void close_file( void *private_stuff )
470 {
471 libavsmash_handler_t *hp = (libavsmash_handler_t *)private_stuff;
472 if( !hp )
473 return;
474 avformat_close_input( &hp->format_ctx );
475 lsmash_close_file( &hp->file_param );
476 lsmash_destroy_root( hp->root );
477 lw_free( hp );
478 }
479
480 lsmash_reader_t libavsmash_reader =
481 {
482 LIBAVSMASH_READER,
483 open_file,
484 get_first_video_track,
485 get_first_audio_track,
486 destroy_disposable,
487 read_video,
488 read_audio,
489 is_keyframe,
490 delay_audio,
491 video_cleanup,
492 audio_cleanup,
493 close_file
494 };
495