Rev 6133 | Rev 6144 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6133 | Rev 6136 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | 2 | ||
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include |
6 | #include |
7 | 7 | ||
8 | #include |
8 | #include |
9 | #include |
9 | #include |
10 | #include |
10 | #include |
11 | #include |
11 | #include |
12 | #include |
12 | #include |
13 | #include "winlib/winlib.h" |
13 | #include "winlib/winlib.h" |
14 | 14 | ||
15 | #include "sound.h" |
15 | #include "sound.h" |
16 | #include "fplay.h" |
16 | #include "fplay.h" |
17 | 17 | ||
18 | #ifdef HAVE_VAAPI |
- | |
19 | int va_check_codec_support(enum AVCodecID id); |
- | |
20 | #endif |
- | |
21 | - | ||
22 | volatile enum player_state player_state = STOP; |
18 | volatile enum player_state player_state = STOP; |
23 | volatile enum player_state decoder_state = PREPARE; |
19 | volatile enum player_state decoder_state = PREPARE; |
24 | volatile enum player_state sound_state = STOP; |
20 | volatile enum player_state sound_state = STOP; |
25 | 21 | ||
26 | uint32_t win_width, win_height; |
22 | uint32_t win_width, win_height; |
27 | 23 | ||
28 | int have_sound = 0; |
24 | int have_sound = 0; |
29 | 25 | ||
30 | uint8_t *decoder_buffer; |
26 | uint8_t *decoder_buffer; |
31 | extern int resampler_size; |
27 | extern int resampler_size; |
32 | 28 | extern int sample_rate; |
|
33 | extern int sample_rate; |
- | |
34 | char *movie_file; |
29 | |
35 | - | ||
36 | void flush_video(vst_t* vst); |
- | |
37 | - | ||
38 | - | ||
39 | int64_t rewind_pos; |
30 | int64_t rewind_pos; |
40 | 31 | ||
41 | int64_t stream_duration; |
32 | int64_t stream_duration; |
42 | 33 | ||
43 | int threads_running = DECODER_THREAD; |
34 | int threads_running = DECODER_THREAD; |
44 | 35 | ||
45 | extern double audio_base; |
36 | extern double audio_base; |
46 | 37 | ||
47 | 38 | ||
48 | double get_audio_base(vst_t* vst) |
- | |
49 | { |
- | |
50 | return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000; |
- | |
51 | }; |
- | |
52 | - | ||
53 | - | ||
54 | int main( int argc, char *argv[]) |
39 | int main( int argc, char *argv[]) |
55 | { |
40 | { |
56 | static vst_t vst; |
41 | static vst_t vst; |
57 | int i, ret; |
42 | int i, ret; |
58 | char *file_name, *dot; |
43 | char *file_name, *dot; |
59 | 44 | ||
60 | if(argc < 2) |
45 | if(argc < 2) |
61 | { |
46 | { |
62 | movie_file = get_moviefile(); |
47 | vst.input_file = get_moviefile(); |
63 | if(movie_file == NULL) |
48 | if(vst.input_file == NULL) |
64 | { |
49 | { |
65 | printf("Please provide a movie file\n"); |
50 | printf("Please provide a movie file\n"); |
66 | return -1; |
51 | return -1; |
67 | } |
52 | } |
68 | } |
53 | } |
69 | else movie_file = argv[1]; |
54 | else vst.input_file = argv[1]; |
70 | 55 | ||
71 | /* register all codecs, demux and protocols */ |
56 | /* register all codecs, demux and protocols */ |
72 | 57 | ||
73 | av_log_set_level(AV_LOG_FATAL); |
58 | av_log_set_level(AV_LOG_FATAL); |
74 | 59 | ||
75 | avcodec_register_all(); |
60 | avcodec_register_all(); |
76 | avdevice_register_all(); |
61 | avdevice_register_all(); |
77 | av_register_all(); |
62 | av_register_all(); |
78 | 63 | ||
79 | if( avformat_open_input(&vst.fCtx, movie_file, NULL, NULL) < 0) |
64 | if( avformat_open_input(&vst.fCtx, vst.input_file, NULL, NULL) < 0) |
80 | { |
65 | { |
81 | printf("Cannot open file %s\n\r", movie_file); |
66 | printf("Cannot open file %s\n\r", vst.input_file); |
82 | return -1; // Couldn't open file |
67 | return -1; // Couldn't open file |
83 | }; |
68 | }; |
84 | 69 | ||
85 | vst.fCtx->flags |= AVFMT_FLAG_GENPTS; |
70 | vst.fCtx->flags |= AVFMT_FLAG_GENPTS; |
86 | 71 | ||
87 | // Retrieve stream information |
72 | // Retrieve stream information |
88 | if(avformat_find_stream_info(vst.fCtx, NULL) < 0) |
73 | if(avformat_find_stream_info(vst.fCtx, NULL) < 0) |
89 | { |
74 | { |
90 | printf("Cannot find streams\n\r"); |
75 | printf("Cannot find streams\n\r"); |
91 | return -1; |
76 | return -1; |
92 | }; |
77 | }; |
93 | 78 | ||
94 | file_name = strrchr(movie_file,'/')+1; |
79 | file_name = strrchr(vst.input_file,'/')+1; |
95 | dot = strrchr(file_name,'.'); |
80 | dot = strrchr(file_name,'.'); |
96 | if(dot) |
81 | if(dot) |
97 | { |
82 | { |
98 | movie_file = malloc(dot-file_name+1); |
83 | vst.input_name = malloc(dot-file_name+1); |
99 | memcpy(movie_file, file_name, dot-file_name); |
84 | memcpy(vst.input_name, file_name, dot-file_name); |
100 | movie_file[dot-file_name] = 0; |
85 | vst.input_name[dot-file_name] = 0; |
101 | } |
86 | } |
102 | else movie_file = file_name; |
87 | else vst.input_name = file_name; |
103 | 88 | ||
104 | stream_duration = vst.fCtx->duration; |
89 | stream_duration = vst.fCtx->duration; |
105 | 90 | ||
106 | // Find the first video stream |
91 | // Find the first video stream |
107 | vst.vStream = -1; |
92 | vst.vStream = -1; |
108 | vst.aStream = -1; |
93 | vst.aStream = -1; |
109 | 94 | ||
110 | for(i=0; i < vst.fCtx->nb_streams; i++) |
95 | for(i=0; i < vst.fCtx->nb_streams; i++) |
111 | { |
96 | { |
112 | if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO |
97 | if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO |
113 | && vst.vStream < 0) |
98 | && vst.vStream < 0) |
114 | { |
99 | { |
115 | vst.vStream = i; |
100 | vst.vStream = i; |
116 | video_time_base = vst.fCtx->streams[i]->time_base; |
101 | vst.video_time_base = vst.fCtx->streams[i]->time_base; |
117 | if(stream_duration == 0) |
102 | if(stream_duration == 0) |
118 | stream_duration = vst.fCtx->streams[i]->duration; |
103 | stream_duration = vst.fCtx->streams[i]->duration; |
119 | } |
104 | } |
120 | 105 | ||
121 | if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO && |
106 | if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO && |
122 | vst.aStream < 0) |
107 | vst.aStream < 0) |
123 | { |
108 | { |
124 | vst.aStream = i; |
109 | vst.aStream = i; |
125 | if(stream_duration == 0) |
110 | vst.audio_time_base = vst.fCtx->streams[i]->time_base; |
- | 111 | if(stream_duration == 0) |
|
126 | stream_duration = vst.fCtx->streams[i]->duration; |
112 | stream_duration = vst.fCtx->streams[i]->duration; |
127 | } |
113 | } |
128 | } |
114 | } |
129 | 115 | ||
130 | if(vst.vStream==-1) |
116 | if(vst.vStream==-1) |
131 | { |
117 | { |
132 | printf("Video stream not detected\n\r"); |
118 | printf("Video stream not detected\n\r"); |
133 | return -1; // Didn't find a video stream |
119 | return -1; // Didn't find a video stream |
134 | }; |
120 | }; |
135 | 121 | ||
136 | // __asm__ __volatile__("int3"); |
122 | // __asm__ __volatile__("int3"); |
137 | 123 | ||
138 | // Get a pointer to the codec context for the video stream |
124 | // Get a pointer to the codec context for the video stream |
139 | vst.vCtx = vst.fCtx->streams[vst.vStream]->codec; |
125 | vst.vCtx = vst.fCtx->streams[vst.vStream]->codec; |
140 | vst.aCtx = vst.fCtx->streams[vst.aStream]->codec; |
126 | vst.aCtx = vst.fCtx->streams[vst.aStream]->codec; |
141 | 127 | ||
142 | vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id); |
128 | vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id); |
143 | printf("codec id %x name %s\n",vst.vCtx->codec_id, vst.vCodec->name); |
129 | |
144 | printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt); |
- | |
145 | - | ||
146 | INIT_LIST_HEAD(&vst.input_list); |
130 | INIT_LIST_HEAD(&vst.input_list); |
147 | INIT_LIST_HEAD(&vst.output_list); |
131 | INIT_LIST_HEAD(&vst.output_list); |
148 | mutex_init(&vst.q_video.lock); |
132 | mutex_init(&vst.q_video.lock); |
149 | mutex_init(&vst.q_audio.lock); |
133 | mutex_init(&vst.q_audio.lock); |
150 | mutex_init(&vst.gpu_lock); |
134 | mutex_init(&vst.gpu_lock); |
151 | mutex_init(&vst.decoder_lock); |
135 | mutex_init(&vst.decoder_lock); |
152 | mutex_init(&vst.input_lock); |
136 | mutex_init(&vst.input_lock); |
153 | mutex_init(&vst.output_lock); |
137 | mutex_init(&vst.output_lock); |
154 | 138 | ||
155 | if(vst.vCodec == NULL) |
139 | if(vst.vCodec == NULL) |
156 | { |
140 | { |
157 | printf("Unsupported codec with id %d for input stream %d\n", |
141 | printf("Unsupported codec with id %d for input stream %d\n", |
158 | vst.vCtx->codec_id, vst.vStream); |
142 | vst.vCtx->codec_id, vst.vStream); |
159 | return -1; // Codec not found |
143 | return -1; |
160 | } |
144 | } |
161 | 145 | ||
- | 146 | vst.Frame = av_frame_alloc(); |
|
- | 147 | if(vst.Frame == NULL) |
|
- | 148 | { |
|
- | 149 | printf("Cannot alloc video frame\n"); |
|
- | 150 | return -1; |
|
- | 151 | }; |
|
- | 152 | ||
162 | if(fplay_init_context(&vst)) |
153 | if(fplay_init_context(&vst)) |
163 | return -1; |
154 | return -1; |
164 | 155 | ||
165 | if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0) |
156 | if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0) |
166 | { |
157 | { |
167 | printf("Error while opening codec for input stream %d\n", |
158 | printf("Error while opening codec for input stream %d\n", |
168 | vst.vStream); |
159 | vst.vStream); |
169 | return -1; // Could not open codec |
160 | return -1; // Could not open codec |
170 | }; |
161 | }; |
171 | 162 | ||
172 | printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt); |
- | |
173 | - | ||
174 | if (vst.aCtx->channels > 0) |
163 | if (vst.aCtx->channels > 0) |
175 | vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels); |
164 | vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels); |
176 | else |
165 | else |
177 | vst.aCtx->request_channels = 2; |
166 | vst.aCtx->request_channels = 2; |
178 | 167 | ||
179 | vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id); |
168 | vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id); |
180 | 169 | ||
181 | if(vst.aCodec) |
170 | if(vst.aCodec) |
182 | { |
171 | { |
183 | if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 ) |
172 | if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 ) |
184 | { |
173 | { |
185 | WAVEHEADER whdr; |
174 | WAVEHEADER whdr; |
186 | int fmt; |
175 | int fmt; |
187 | int channels; |
176 | int channels; |
188 | 177 | ||
189 | printf("audio stream rate %d channels %d format %d\n", |
178 | printf("audio stream rate %d channels %d format %d\n", |
190 | vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt ); |
179 | vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt ); |
191 | whdr.riff_id = 0x46464952; |
180 | whdr.riff_id = 0x46464952; |
192 | whdr.riff_format = 0x45564157; |
181 | whdr.riff_format = 0x45564157; |
193 | whdr.wFormatTag = 0x01; |
182 | whdr.wFormatTag = 0x01; |
194 | whdr.nSamplesPerSec = vst.aCtx->sample_rate; |
183 | whdr.nSamplesPerSec = vst.aCtx->sample_rate; |
195 | whdr.nChannels = 2; |
184 | whdr.nChannels = 2; |
196 | whdr.wBitsPerSample = 16; |
185 | whdr.wBitsPerSample = 16; |
197 | 186 | ||
198 | sample_rate = vst.aCtx->sample_rate; |
187 | sample_rate = vst.aCtx->sample_rate; |
199 | 188 | ||
200 | fmt = test_wav(&whdr); |
189 | fmt = test_wav(&whdr); |
201 | 190 | ||
202 | if( init_audio(fmt) ) |
191 | if( init_audio(fmt) ) |
203 | { |
192 | { |
204 | decoder_buffer = (uint8_t*)av_mallocz(192000*2+64); |
193 | decoder_buffer = (uint8_t*)av_mallocz(192000*2+64); |
205 | if( decoder_buffer != NULL ) |
194 | if( decoder_buffer != NULL ) |
206 | { |
195 | { |
207 | mutex_init(&astream.lock); |
196 | mutex_init(&astream.lock); |
208 | astream.count = 0; |
197 | astream.count = 0; |
209 | astream.buffer = (char *)av_mallocz(192000*3); |
198 | astream.buffer = (char *)av_mallocz(192000*3); |
210 | if( astream.buffer != NULL ) |
199 | if( astream.buffer != NULL ) |
211 | have_sound = 1; |
200 | have_sound = 1; |
212 | else |
201 | else |
213 | av_free(decoder_buffer); |
202 | av_free(decoder_buffer); |
214 | } |
203 | } |
215 | if( have_sound == 0) |
204 | if( have_sound == 0) |
216 | { |
205 | { |
217 | printf("Not enough memory for audio buffers\n"); |
206 | printf("Not enough memory for audio buffers\n"); |
218 | } |
207 | } |
219 | } |
208 | } |
220 | } |
209 | } |
221 | else printf("Cannot open audio codec\n\r"); |
210 | else printf("Cannot open audio codec\n\r"); |
222 | } |
211 | } |
223 | else printf("Unsupported audio codec!\n"); |
212 | else printf("Unsupported audio codec!\n"); |
224 | 213 | ||
225 | if(!init_video(&vst)) |
214 | mutex_lock(&vst.decoder_lock); |
226 | return 0; |
215 | create_thread(video_thread, &vst, 1024*1024); |
227 | - | ||
228 | mutex_lock_timeout(&vst.decoder_lock, 3000); |
216 | if(mutex_lock_timeout(&vst.decoder_lock, 3000) == 0) |
- | 217 | return -1; |
|
229 | 218 | ||
230 | decoder(&vst); |
219 | decoder(&vst); |
231 | 220 | ||
232 | 221 | ||
233 | //__asm__ __volatile__("int3"); |
222 | //__asm__ __volatile__("int3"); |
234 | 223 | ||
235 | while( threads_running & |
224 | while( threads_running & |
236 | (AUDIO_THREAD | VIDEO_THREAD)) |
225 | (AUDIO_THREAD | VIDEO_THREAD)) |
237 | delay(1); |
226 | delay(1); |
238 | 227 | ||
239 | if(astream.lock.handle) |
228 | if(astream.lock.handle) |
240 | mutex_destroy(&astream.lock); |
229 | mutex_destroy(&astream.lock); |
241 | 230 | ||
242 | mutex_destroy(&vst.q_video.lock); |
231 | mutex_destroy(&vst.q_video.lock); |
243 | mutex_destroy(&vst.q_audio.lock); |
232 | mutex_destroy(&vst.q_audio.lock); |
244 | mutex_destroy(&vst.decoder_lock); |
233 | mutex_destroy(&vst.decoder_lock); |
245 | return 0; |
234 | return 0; |
246 | } |
235 | } |
247 | 236 | ||
248 | 237 | ||
249 | static int load_frame(vst_t *vst) |
238 | static int load_frame(vst_t *vst) |
250 | { |
239 | { |
251 | AVPacket packet; |
240 | AVPacket packet; |
252 | int err; |
241 | int err; |
253 | 242 | ||
254 | err = av_read_frame(vst->fCtx, &packet); |
243 | err = av_read_frame(vst->fCtx, &packet); |
255 | if( err == 0) |
244 | if( err == 0) |
256 | { |
245 | { |
257 | if(packet.stream_index == vst->vStream) |
246 | if(packet.stream_index == vst->vStream) |
258 | put_packet(&vst->q_video, &packet); |
247 | put_packet(&vst->q_video, &packet); |
259 | else if( (packet.stream_index == vst->aStream) && |
248 | else if( (packet.stream_index == vst->aStream) && |
260 | (have_sound != 0) ) |
249 | (have_sound != 0) ) |
261 | { |
250 | { |
262 | put_packet(&vst->q_audio, &packet); |
251 | put_packet(&vst->q_audio, &packet); |
263 | if(audio_base == -1.0) |
252 | if(audio_base == -1.0) |
264 | { |
253 | { |
265 | if (packet.pts != AV_NOPTS_VALUE) |
254 | if (packet.pts != AV_NOPTS_VALUE) |
266 | audio_base = get_audio_base(vst) * packet.pts; |
255 | audio_base = get_audio_base(vst) * packet.pts; |
267 | // printf("audio base %f\n", audio_base); |
256 | // printf("audio base %f\n", audio_base); |
268 | }; |
257 | }; |
269 | } |
258 | } |
270 | else av_free_packet(&packet); |
259 | else av_free_packet(&packet); |
271 | } |
260 | } |
272 | else if (err != AVERROR_EOF) |
261 | else if (err != AVERROR_EOF) |
273 | printf("av_read_frame: error %x\n", err); |
262 | printf("av_read_frame: error %x\n", err); |
274 | 263 | ||
275 | return err; |
264 | return err; |
276 | } |
265 | } |
277 | 266 | ||
278 | 267 | ||
279 | 268 | ||
280 | static int fill_queue(vst_t* vst) |
269 | static int fill_queue(vst_t* vst) |
281 | { |
270 | { |
282 | int err = 0; |
271 | int err = 0; |
283 | AVPacket packet; |
272 | AVPacket packet; |
284 | 273 | ||
285 | while( (vst->q_video.size < 4*1024*1024) && !err ) |
274 | while( (vst->q_video.size < 4*1024*1024) && !err ) |
286 | err = load_frame(vst); |
275 | err = load_frame(vst); |
287 | 276 | ||
288 | return err; |
277 | return err; |
289 | }; |
278 | }; |
290 | 279 | ||
291 | 280 | ||
292 | static void flush_all(vst_t* vst) |
281 | static void flush_all(vst_t* vst) |
293 | { |
282 | { |
294 | AVPacket packet; |
283 | AVPacket packet; |
295 | 284 | ||
296 | avcodec_flush_buffers(vst->vCtx); |
285 | avcodec_flush_buffers(vst->vCtx); |
297 | avcodec_flush_buffers(vst->aCtx); |
286 | avcodec_flush_buffers(vst->aCtx); |
298 | while( get_packet(&vst->q_video, &packet) != 0) |
287 | while( get_packet(&vst->q_video, &packet) != 0) |
299 | av_free_packet(&packet); |
288 | av_free_packet(&packet); |
300 | 289 | ||
301 | while( get_packet(&vst->q_audio, &packet)!= 0) |
290 | while( get_packet(&vst->q_audio, &packet)!= 0) |
302 | av_free_packet(&packet); |
291 | av_free_packet(&packet); |
303 | 292 | ||
304 | flush_video(vst); |
293 | flush_video(vst); |
305 | 294 | ||
306 | astream.count = 0; |
295 | astream.count = 0; |
307 | }; |
296 | }; |
308 | 297 | ||
309 | void decoder(vst_t* vst) |
298 | void decoder(vst_t* vst) |
310 | { |
299 | { |
311 | int eof; |
300 | int eof; |
312 | AVPacket packet; |
301 | AVPacket packet; |
313 | int ret, vret, aret; |
302 | int ret, vret, aret; |
314 | 303 | ||
315 | int64_t min_pos, max_pos; |
304 | int64_t min_pos, max_pos; |
316 | 305 | ||
317 | // av_log_set_level(AV_LOG_DEBUG); |
306 | // av_log_set_level(AV_LOG_DEBUG); |
318 | 307 | ||
319 | while( player_state != CLOSED ) |
308 | while( player_state != CLOSED ) |
320 | { |
309 | { |
321 | int err; |
310 | int err; |
322 | 311 | ||
323 | switch(decoder_state) |
312 | switch(decoder_state) |
324 | { |
313 | { |
325 | case PREPARE: |
314 | case PREPARE: |
326 | eof = fill_queue(vst); |
315 | eof = fill_queue(vst); |
327 | 316 | ||
328 | do |
317 | do |
329 | { |
318 | { |
330 | if( (vst->q_video.size < 4*1024*1024) && |
319 | if( (vst->q_video.size < 4*1024*1024) && |
331 | (eof == 0) ) |
320 | (eof == 0) ) |
332 | { |
321 | { |
333 | eof = load_frame(vst); |
322 | eof = load_frame(vst); |
334 | } |
323 | } |
335 | decode_video(vst); |
324 | decode_video(vst); |
336 | ret = decode_audio(vst->aCtx, &vst->q_audio); |
325 | ret = decode_audio(vst->aCtx, &vst->q_audio); |
337 | }while(astream.count < resampler_size*2 && ret == 1); |
326 | }while(astream.count < resampler_size*2 && ret == 1); |
338 | 327 | ||
339 | sound_state = PREPARE; |
328 | sound_state = PREPARE; |
340 | decoder_state = PLAY; |
329 | decoder_state = PLAY; |
341 | player_state = PLAY; |
330 | player_state = PLAY; |
342 | 331 | ||
343 | case PLAY: |
332 | case PLAY: |
344 | if( (vst->q_video.size < 4*1024*1024) && |
333 | if( (vst->q_video.size < 4*1024*1024) && |
345 | (eof == 0) ) |
334 | (eof == 0) ) |
346 | { |
335 | { |
347 | eof = load_frame(vst); |
336 | eof = load_frame(vst); |
348 | } |
337 | } |
349 | vret = decode_video(vst); |
338 | vret = decode_video(vst); |
350 | aret = decode_audio(vst->aCtx, &vst->q_audio); |
339 | aret = decode_audio(vst->aCtx, &vst->q_audio); |
351 | ret = vret | aret; |
340 | ret = vret | aret; |
352 | 341 | ||
353 | if( eof && !ret) |
342 | if( eof && !ret) |
354 | { |
343 | { |
355 | decoder_state = STOP; |
344 | decoder_state = STOP; |
356 | continue; |
345 | continue; |
357 | }; |
346 | }; |
358 | 347 | ||
359 | if( (vret & aret) == -1) |
348 | if( (vret & aret) == -1) |
360 | { |
349 | { |
361 | if( (vst->q_video.size < 4*1024*1024) && |
350 | if( (vst->q_video.size < 4*1024*1024) && |
362 | (eof == 0) ) |
351 | (eof == 0) ) |
363 | { |
352 | { |
364 | eof = load_frame(vst); |
353 | eof = load_frame(vst); |
365 | yield(); |
354 | yield(); |
366 | continue; |
355 | continue; |
367 | }; |
356 | }; |
368 | delay(1); |
357 | delay(1); |
369 | continue; |
358 | continue; |
370 | } |
359 | } |
371 | 360 | yield(); |
|
372 | yield(); |
- | |
373 | continue; |
361 | continue; |
374 | 362 | ||
375 | case STOP: |
363 | case STOP: |
376 | delay(1); |
364 | delay(1); |
377 | continue; |
365 | continue; |
378 | 366 | ||
379 | 367 | ||
380 | case PLAY_2_STOP: |
368 | case PLAY_2_STOP: |
381 | while(sound_state != STOP) |
369 | while(sound_state != STOP) |
382 | delay(1); |
370 | delay(1); |
383 | 371 | ||
384 | flush_all(vst); |
372 | flush_all(vst); |
385 | 373 | ||
386 | if (vst->fCtx->start_time != AV_NOPTS_VALUE) |
374 | if (vst->fCtx->start_time != AV_NOPTS_VALUE) |
387 | rewind_pos = vst->fCtx->start_time; |
375 | rewind_pos = vst->fCtx->start_time; |
388 | else |
376 | else |
389 | rewind_pos = 0; |
377 | rewind_pos = 0; |
390 | 378 | ||
391 | ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN, |
379 | ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN, |
392 | rewind_pos, INT64_MAX, 0); |
380 | rewind_pos, INT64_MAX, 0); |
393 | 381 | ||
394 | decoder_state = STOP; |
382 | decoder_state = STOP; |
395 | break; |
383 | break; |
396 | 384 | ||
397 | case REWIND: |
385 | case REWIND: |
398 | while(sound_state != STOP) |
386 | while(sound_state != STOP) |
399 | yield(); |
387 | yield(); |
400 | 388 | ||
401 | flush_all(vst); |
389 | flush_all(vst); |
402 | int opts = 0; |
390 | int opts = 0; |
403 | if(rewind_pos < 0) |
391 | if(rewind_pos < 0) |
404 | { |
392 | { |
405 | rewind_pos = -rewind_pos; |
393 | rewind_pos = -rewind_pos; |
406 | opts = AVSEEK_FLAG_BACKWARD; |
394 | opts = AVSEEK_FLAG_BACKWARD; |
407 | }; |
395 | }; |
408 | 396 | ||
409 | if (vst->fCtx->start_time != AV_NOPTS_VALUE) |
397 | if (vst->fCtx->start_time != AV_NOPTS_VALUE) |
410 | rewind_pos += vst->fCtx->start_time; |
398 | rewind_pos += vst->fCtx->start_time; |
411 | 399 | ||
412 | // printf("rewind %8"PRId64"\n", rewind_pos); |
400 | // printf("rewind %8"PRId64"\n", rewind_pos); |
413 | min_pos = rewind_pos - 1000000; |
401 | min_pos = rewind_pos - 1000000; |
414 | max_pos = rewind_pos + 1000000; |
402 | max_pos = rewind_pos + 1000000; |
415 | 403 | ||
416 | ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN, |
404 | ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN, |
417 | rewind_pos, INT64_MAX, 0); |
405 | rewind_pos, INT64_MAX, 0); |
418 | if (ret < 0) |
406 | if (ret < 0) |
419 | { |
407 | { |
420 | printf("could not seek to position %f\n", |
408 | printf("could not seek to position %f\n", |
421 | (double)rewind_pos / AV_TIME_BASE); |
409 | (double)rewind_pos / AV_TIME_BASE); |
422 | } |
410 | } |
423 | decoder_state = PREPARE; |
411 | decoder_state = PREPARE; |
424 | break; |
412 | break; |
425 | } |
413 | } |
426 | }; |
414 | }; |
427 | };>>>>>>>>>>>>>> |
415 | };>>>>>>>>>>>>>> |