Subversion Repositories Kolibri OS

Rev

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
};