/src/vlc/modules/demux/mp4/fragments.c
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * fragments.c : MP4 fragments |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001-2015 VLC authors and VideoLAN |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | #ifdef HAVE_CONFIG_H |
21 | | # include "config.h" |
22 | | #endif |
23 | | |
24 | | #include "fragments.h" |
25 | | #include <limits.h> |
26 | | |
27 | | void MP4_Fragments_Index_Delete( mp4_fragments_index_t *p_index ) |
28 | 0 | { |
29 | 0 | if( p_index ) |
30 | 0 | { |
31 | 0 | free( p_index->pi_pos ); |
32 | 0 | free( p_index->p_times ); |
33 | 0 | free( p_index ); |
34 | 0 | } |
35 | 0 | } |
36 | | |
37 | | mp4_fragments_index_t * MP4_Fragments_Index_New( unsigned i_tracks, unsigned i_num ) |
38 | 0 | { |
39 | 0 | if( !i_tracks || !i_num || SIZE_MAX / i_num < i_tracks ) |
40 | 0 | return NULL; |
41 | 0 | mp4_fragments_index_t *p_index = malloc( sizeof(*p_index) ); |
42 | 0 | if( p_index ) |
43 | 0 | { |
44 | 0 | p_index->p_times = calloc( (size_t)i_num * i_tracks, sizeof(*p_index->p_times) ); |
45 | 0 | p_index->pi_pos = calloc( i_num, sizeof(*p_index->pi_pos) ); |
46 | 0 | if( !p_index->p_times || !p_index->pi_pos ) |
47 | 0 | { |
48 | 0 | MP4_Fragments_Index_Delete( p_index ); |
49 | 0 | return NULL; |
50 | 0 | } |
51 | 0 | p_index->i_entries = i_num; |
52 | 0 | p_index->i_last_time = 0; |
53 | 0 | p_index->i_tracks = i_tracks; |
54 | 0 | } |
55 | 0 | return p_index; |
56 | 0 | } |
57 | | |
58 | | stime_t MP4_Fragment_Index_GetTrackStartTime( mp4_fragments_index_t *p_index, |
59 | | unsigned i_track_index, uint64_t i_moof_pos ) |
60 | 0 | { |
61 | 0 | for( size_t i=0; i<p_index->i_entries; i++ ) |
62 | 0 | { |
63 | 0 | if( p_index->pi_pos[i] >= i_moof_pos ) |
64 | 0 | return p_index->p_times[i * p_index->i_tracks + i_track_index]; |
65 | 0 | } |
66 | 0 | return 0; |
67 | 0 | } |
68 | | |
69 | | stime_t MP4_Fragment_Index_GetTracksDuration( const mp4_fragments_index_t *p_index ) |
70 | 0 | { |
71 | 0 | return p_index->i_last_time; |
72 | 0 | } |
73 | | |
74 | | bool MP4_Fragments_Index_Lookup( mp4_fragments_index_t *p_index, stime_t *pi_time, |
75 | | uint64_t *pi_pos, unsigned i_track_index ) |
76 | 0 | { |
77 | 0 | if( *pi_time >= p_index->i_last_time || p_index->i_entries < 1 || |
78 | 0 | i_track_index >= p_index->i_tracks ) |
79 | 0 | return false; |
80 | | |
81 | 0 | for( size_t i=1; i<p_index->i_entries; i++ ) |
82 | 0 | { |
83 | 0 | if( p_index->p_times[i * p_index->i_tracks + i_track_index] > *pi_time ) |
84 | 0 | { |
85 | 0 | *pi_time = p_index->p_times[(i - 1) * p_index->i_tracks + i_track_index]; |
86 | 0 | *pi_pos = p_index->pi_pos[i - 1]; |
87 | 0 | return true; |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | 0 | *pi_time = p_index->p_times[(size_t)(p_index->i_entries - 1) * p_index->i_tracks]; |
92 | 0 | *pi_pos = p_index->pi_pos[p_index->i_entries - 1]; |
93 | 0 | return true; |
94 | 0 | } |
95 | | |
96 | | #ifdef MP4_VERBOSE |
97 | | void MP4_Fragments_Index_Dump( vlc_object_t *p_obj, const mp4_fragments_index_t *p_index, |
98 | | uint32_t i_movie_timescale ) |
99 | 0 | { |
100 | 0 | for( size_t i=0; i<p_index->i_entries; i++ ) |
101 | 0 | { |
102 | 0 | char *psz_starts = NULL; |
103 | |
|
104 | 0 | stime_t i_end; |
105 | 0 | if( i + 1 == p_index->i_entries ) |
106 | 0 | i_end = p_index->i_last_time; |
107 | 0 | else |
108 | 0 | i_end = p_index->p_times[(i + 1) * p_index->i_tracks]; |
109 | |
|
110 | 0 | for( unsigned j=0; j<p_index->i_tracks; j++ ) |
111 | 0 | { |
112 | 0 | char *psz_start = NULL; |
113 | 0 | if( 0 < asprintf( &psz_start, "%s [%u]%"PRId64"ms ", |
114 | 0 | (psz_starts) ? psz_starts : "", j, |
115 | 0 | INT64_C( 1000 ) * p_index->p_times[i * p_index->i_tracks + j] / i_movie_timescale ) ) |
116 | 0 | { |
117 | 0 | free( psz_starts ); |
118 | 0 | psz_starts = psz_start; |
119 | 0 | } |
120 | 0 | } |
121 | |
|
122 | 0 | msg_Dbg( p_obj, "fragment offset @%"PRId64" %"PRId64"ms, start %s", |
123 | 0 | p_index->pi_pos[i], |
124 | 0 | INT64_C( 1000 ) * i_end / i_movie_timescale, psz_starts ); |
125 | |
|
126 | 0 | free( psz_starts ); |
127 | 0 | } |
128 | 0 | } |
129 | | #endif |