comparison libmpdemux/demux_nuv.c @ 4065:763a0e7e0521

seek patch by Panagoitis Issaris
author alex
date Wed, 09 Jan 2002 17:09:21 +0000
parents 79e1c3c0e634
children 508a4e7df349
comparison
equal deleted inserted replaced
4064:3c747168eb6e 4065:763a0e7e0521
15 #include "help_mp.h" 15 #include "help_mp.h"
16 #include "stream.h" 16 #include "stream.h"
17 #include "demuxer.h" 17 #include "demuxer.h"
18 #include "stheader.h" 18 #include "stheader.h"
19 #include "nuppelvideo.h" 19 #include "nuppelvideo.h"
20 //#include "RTjpegN.h"
21 //#include "minilzo.h"
22 20
23 21
24 struct nuv_signature 22 struct nuv_signature
25 { 23 {
26 char finfo[12]; /* "NuppelVideo" + \0 */ 24 char finfo[12]; /* "NuppelVideo" + \0 */
27 char version[5]; /* "0.05" + \0 */ 25 char version[5]; /* "0.05" + \0 */
28 }; 26 };
29 27
30 28 typedef struct _nuv_position_t nuv_position_t;
29
30 struct _nuv_position_t
31 {
32 off_t offset;
33 float time;
34 int frame;
35 nuv_position_t* next;
36 };
37
38 typedef struct _nuv_info_t
39 {
40 int current_audio_frame;
41 int current_video_frame;
42 nuv_position_t *index_list;
43 nuv_position_t *current_position;
44 } nuv_priv_t;
45
46
47 /**
48 * Seek to a position relative to the current position, indicated in time.
49 */
31 void demux_seek_nuv ( demuxer_t *demuxer, float rel_seek_secs, int flags ) 50 void demux_seek_nuv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
32 { 51 {
33 } 52 #define MAX_TIME 1000000
34 53 nuv_priv_t* priv = demuxer->priv;
35
36 int demux_nuv_fill_buffer ( demuxer_t *demuxer )
37 {
38 struct rtframeheader rtjpeg_frameheader; 54 struct rtframeheader rtjpeg_frameheader;
39 int orig_pos; 55 int orig_pos;
56 int curr_pos;
57 float current_time = 0;
58 float start_time = MAX_TIME;
59 float target_time = start_time + rel_seek_secs * 1000; /* target_time, start_time are ms, rel_seek_secs s */
60
61 orig_pos = stream_tell ( demuxer->stream );
62
63 if ( rel_seek_secs > 0 )
64 {
65 /* Seeking forward */
66
67
68 while(current_time < target_time )
69 {
70 if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader))
71 return; /* EOF */
72
73 if ( rtjpeg_frameheader.frametype == 'V' )
74 {
75 priv->current_position->next = (nuv_position_t*) malloc ( sizeof ( nuv_position_t ) );
76 priv->current_position = priv->current_position->next;
77 priv->current_position->frame = priv->current_video_frame++;
78 priv->current_position->time = rtjpeg_frameheader.timecode;
79 priv->current_position->offset = orig_pos;
80 priv->current_position->next = NULL;
81
82 if ( start_time == MAX_TIME )
83 {
84 start_time = rtjpeg_frameheader.timecode;
85 /* Recalculate target time with real start time */
86 target_time = start_time + rel_seek_secs*1000;
87 }
88
89 current_time = rtjpeg_frameheader.timecode;
90
91 curr_pos = stream_tell ( demuxer->stream );
92 stream_seek ( demuxer->stream, curr_pos + rtjpeg_frameheader.packetlength );
93
94 /* Adjust current sequence pointer */
95 }
96 else if ( rtjpeg_frameheader.frametype == 'A' )
97 {
98 if ( start_time == MAX_TIME )
99 {
100 start_time = rtjpeg_frameheader.timecode;
101 /* Recalculate target time with real start time */
102 target_time = start_time + rel_seek_secs * 1000;
103 }
104 current_time = rtjpeg_frameheader.timecode;
105
106
107 curr_pos = stream_tell ( demuxer->stream );
108 stream_seek ( demuxer->stream, curr_pos + rtjpeg_frameheader.packetlength );
109 }
110 }
111 }
112 else
113 {
114 /* Seeking backward */
115 nuv_position_t* p;
116 start_time = priv->current_position->time;
117
118 /* Recalculate target time with real start time */
119 target_time = start_time + rel_seek_secs * 1000;
120
121
122 if(target_time < 0)
123 target_time = 0;
124
125 // Search the target time in the index list, get the offset
126 // and go to that offset.
127 p = priv->index_list;
128 while ( ( p->next != NULL ) && ( p->time < target_time ) )
129 {
130 p = p->next;
131 }
132 stream_seek ( demuxer->stream, p->offset );
133 priv->current_video_frame = p->frame;
134 }
135 }
136
137
138 int demux_nuv_fill_buffer ( demuxer_t *demuxer )
139 {
140 struct rtframeheader rtjpeg_frameheader;
141 int orig_pos;
142 nuv_priv_t* priv = demuxer->priv;
40 143
41 orig_pos = stream_tell ( demuxer->stream ); 144 orig_pos = stream_tell ( demuxer->stream );
42 if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader)) 145 if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader))
43 return 0; /* EOF */ 146 return 0; /* EOF */
44 147
56 159
57 if (((rtjpeg_frameheader.frametype == 'D') && 160 if (((rtjpeg_frameheader.frametype == 'D') &&
58 (rtjpeg_frameheader.comptype == 'R')) || 161 (rtjpeg_frameheader.comptype == 'R')) ||
59 (rtjpeg_frameheader.frametype == 'V')) 162 (rtjpeg_frameheader.frametype == 'V'))
60 { 163 {
164 if ( rtjpeg_frameheader.frametype == 'V' )
165 {
166 priv->current_video_frame++;
167 priv->current_position->next = (nuv_position_t*) malloc(sizeof(nuv_position_t));
168 priv->current_position = priv->current_position->next;
169 priv->current_position->frame = priv->current_video_frame;
170 priv->current_position->time = rtjpeg_frameheader.timecode;
171 priv->current_position->offset = orig_pos;
172 priv->current_position->next = NULL;
173 }
61 /* put RTjpeg tables, Video info to video buffer */ 174 /* put RTjpeg tables, Video info to video buffer */
62 stream_seek ( demuxer->stream, orig_pos ); 175 stream_seek ( demuxer->stream, orig_pos );
63 ds_read_packet ( demuxer->video, demuxer->stream, rtjpeg_frameheader.packetlength + 12, 176 ds_read_packet ( demuxer->video, demuxer->stream, rtjpeg_frameheader.packetlength + 12,
64 rtjpeg_frameheader.timecode / 1000, orig_pos, 0 ); 177 rtjpeg_frameheader.timecode / 1000, orig_pos, 0 );
65 } 178
66 179
180 } else
67 /* copy PCM only */ 181 /* copy PCM only */
68 if (demuxer->audio && (rtjpeg_frameheader.frametype == 'A') && 182 if (demuxer->audio && (rtjpeg_frameheader.frametype == 'A') &&
69 (rtjpeg_frameheader.comptype == '0')) 183 (rtjpeg_frameheader.comptype == '0'))
70 { 184 {
185 priv->current_audio_frame++;
71 /* put Audio to audio buffer */ 186 /* put Audio to audio buffer */
72 ds_read_packet ( demuxer->audio, demuxer->stream, rtjpeg_frameheader.packetlength, 187 ds_read_packet ( demuxer->audio, demuxer->stream, rtjpeg_frameheader.packetlength,
73 rtjpeg_frameheader.timecode / 1000, orig_pos + 12, 0 ); 188 rtjpeg_frameheader.timecode / 1000, orig_pos + 12, 0 );
74 } 189 }
75 190
83 sh_audio_t *sh_audio = NULL; 198 sh_audio_t *sh_audio = NULL;
84 struct rtfileheader rtjpeg_fileheader; 199 struct rtfileheader rtjpeg_fileheader;
85 struct rtframeheader rtjpeg_frameheader; 200 struct rtframeheader rtjpeg_frameheader;
86 unsigned long int tbls[128]; 201 unsigned long int tbls[128];
87 int bytes_read; 202 int bytes_read;
203 nuv_priv_t* priv = (nuv_priv_t*) malloc ( sizeof ( nuv_priv_t) );
204 demuxer->priv = priv;
205 priv->current_audio_frame = 0;
206 priv->current_video_frame = 0;
207
88 208
89 /* Go to the start */ 209 /* Go to the start */
90 stream_reset(demuxer->stream); 210 stream_reset(demuxer->stream);
91 stream_seek(demuxer->stream, 0); 211 stream_seek(demuxer->stream, 0);
92 212
129 249
130 /* Get the FPS */ 250 /* Get the FPS */
131 sh_video->fps = rtjpeg_fileheader.fps; 251 sh_video->fps = rtjpeg_fileheader.fps;
132 sh_video->frametime = 1 / sh_video->fps; 252 sh_video->frametime = 1 / sh_video->fps;
133 253
134 #if 1
135 if (rtjpeg_fileheader.audioblocks != 0) 254 if (rtjpeg_fileheader.audioblocks != 0)
136 { 255 {
137 sh_audio = new_sh_audio(demuxer, 0); 256 sh_audio = new_sh_audio(demuxer, 0);
138 demuxer->audio->sh = sh_audio; 257 demuxer->audio->sh = sh_audio;
139 sh_audio->ds = demuxer->audio; 258 sh_audio->ds = demuxer->audio;
150 sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels* 269 sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels*
151 sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8; 270 sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8;
152 sh_audio->wf->nBlockAlign = sh_audio->channels * 2; 271 sh_audio->wf->nBlockAlign = sh_audio->channels * 2;
153 sh_audio->wf->cbSize = 0; 272 sh_audio->wf->cbSize = 0;
154 } 273 }
155 #endif 274
275 priv->index_list = (nuv_position_t*) malloc(sizeof(nuv_position_t));
276 priv->index_list->frame = 0;
277 priv->index_list->time = 0;
278 priv->index_list->offset = stream_tell ( demuxer->stream );
279 priv->index_list->next = NULL;
280 priv->current_position = priv->index_list;
156 281
157 return demuxer; 282 return demuxer;
158 } 283 }
159 284
160 int nuv_check_file ( demuxer_t* demuxer ) 285 int nuv_check_file ( demuxer_t* demuxer )