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