Subversion Repositories Kolibri OS

Rev

Rev 6136 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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