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