Subversion Repositories Kolibri OS

Rev

Rev 6301 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4438 Serge 1
 
2
3
 
4
#include 
5
#include 
6
#include 
7
8
 
9
#include 
10
#include 
11
#include 
12
#include 
13
#include "winlib/winlib.h"
5021 Serge 14
4438 Serge 15
 
16
#include "fplay.h"
17
18
 
19
volatile enum player_state decoder_state = PREPARE;
20
volatile enum player_state sound_state   = STOP;
21
22
 
23
24
 
6121 serge 25
extern int resampler_size;
4438 Serge 26
extern int sample_rate;
27
28
 
29
30
 
31
32
 
6658 serge 33
5603 serge 34
 
4438 Serge 35
{
36
    static vst_t vst;
6117 serge 37
    int i, ret;
38
    char *file_name, *dot;
4438 Serge 39
40
 
41
    {
42
        vst.input_file = get_moviefile();
6136 serge 43
        if(vst.input_file == NULL)
44
        {
4438 Serge 45
            printf("Please provide a movie file\n");
46
            return -1;
47
        }
48
    }
49
    else vst.input_file = argv[1];
6136 serge 50
4438 Serge 51
 
52
53
 
54
55
 
56
    avdevice_register_all();
57
    av_register_all();
58
59
 
6136 serge 60
    {
4438 Serge 61
        printf("Cannot open file %s\n\r", vst.input_file);
6136 serge 62
        return -1; // Couldn't open file
4438 Serge 63
    };
64
65
 
6117 serge 66
4438 Serge 67
 
6117 serge 68
    {
4438 Serge 69
        printf("Cannot find streams\n\r");
70
        return -1;
71
    };
72
73
 
6136 serge 74
    dot = strrchr(file_name,'.');
4438 Serge 75
    if(dot)
76
    {
77
        vst.input_name = malloc(dot-file_name+1);
6136 serge 78
        memcpy(vst.input_name, file_name, dot-file_name);
79
        vst.input_name[dot-file_name] = 0;
80
    }
4438 Serge 81
    else vst.input_name = file_name;
6136 serge 82
4438 Serge 83
 
6117 serge 84
4438 Serge 85
 
6117 serge 86
    vst.aStream = -1;
87
88
 
89
    {
4438 Serge 90
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
6117 serge 91
            && vst.vStream < 0)
92
        {
4438 Serge 93
            vst.vStream = i;
6117 serge 94
            vst.video_time_base = vst.fCtx->streams[i]->time_base;
6136 serge 95
            if(stream_duration == 0)
4438 Serge 96
               stream_duration = vst.fCtx->streams[i]->duration;
6117 serge 97
        }
98
4438 Serge 99
 
6117 serge 100
           vst.aStream < 0)
101
        {
4438 Serge 102
            vst.aStream = i;
6117 serge 103
            if(stream_duration == 0)
4438 Serge 104
               stream_duration = vst.fCtx->streams[i]->duration;
6117 serge 105
        }
4438 Serge 106
    }
107
108
 
6117 serge 109
    {
4438 Serge 110
        printf("Video stream not detected\n\r");
111
        return -1; // Didn't find a video stream
112
    };
113
114
 
115
 
6133 serge 116
    INIT_LIST_HEAD(&vst.output_list);
117
    mutex_init(&vst.q_video.lock);
118
    mutex_init(&vst.q_audio.lock);
119
    mutex_init(&vst.gpu_lock);
120
    mutex_init(&vst.decoder_lock);
121
    mutex_init(&vst.input_lock);
122
    mutex_init(&vst.output_lock);
123
124
 
6144 serge 125
    vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
126
4438 Serge 127
 
6658 serge 128
129
 
6144 serge 130
        return -1;
6136 serge 131
132
 
6144 serge 133
    vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id);
6117 serge 134
    if(vst.aCodec)
135
    {
4438 Serge 136
        if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 )
6117 serge 137
        {
4438 Serge 138
            WAVEHEADER       whdr;
139
            int fmt;
140
            int channels;
141
142
 
143
            vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt );
6117 serge 144
            whdr.riff_id = 0x46464952;
4438 Serge 145
            whdr.riff_format = 0x45564157;
146
            whdr.wFormatTag = 0x01;
147
            whdr.nSamplesPerSec = vst.aCtx->sample_rate;
6117 serge 148
            whdr.nChannels = 2;
4438 Serge 149
            whdr.wBitsPerSample = 16;
150
151
 
6117 serge 152
4438 Serge 153
 
6301 serge 154
4438 Serge 155
 
6301 serge 156
            {
4438 Serge 157
                decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
158
                if( decoder_buffer != NULL )
159
                {
160
                    mutex_init(&astream.lock);
5603 serge 161
                    astream.count  = 0;
4438 Serge 162
                    astream.buffer = (char *)av_mallocz(192000*3);
163
                    if( astream.buffer != NULL )
164
                        vst.has_sound = 1;
6144 serge 165
                    else
4438 Serge 166
                        av_free(decoder_buffer);
167
                }
168
                if( vst.has_sound == 0)
6144 serge 169
                {
4438 Serge 170
                        printf("Not enough memory for audio buffers\n");
171
                }
172
            }
173
        }
174
        else printf("Cannot open audio codec\n\r");
175
    }
176
    else printf("Unsupported audio codec!\n");
177
178
 
6136 serge 179
    create_thread(video_thread, &vst, 1024*1024);
180
    if(mutex_lock_timeout(&vst.decoder_lock, 3000) == 0)
181
        return -1;
182
4438 Serge 183
 
6117 serge 184
4438 Serge 185
 
186
 
187
188
 
5603 serge 189
           (AUDIO_THREAD | VIDEO_THREAD))
190
           delay(1);
191
4438 Serge 192
 
5603 serge 193
        mutex_destroy(&astream.lock);
194
4438 Serge 195
 
6658 serge 196
    avcodec_close(vst.vCtx);
197
198
 
6117 serge 199
    mutex_destroy(&vst.q_audio.lock);
200
    mutex_destroy(&vst.decoder_lock);
6133 serge 201
6144 serge 202
 
4438 Serge 203
}
204
205
 
206
 
6117 serge 207
{
4438 Serge 208
    AVPacket  packet;
209
    int err;
210
211
 
6117 serge 212
    if( err == 0)
4438 Serge 213
    {
214
        if(packet.stream_index == vst->vStream)
6117 serge 215
            put_packet(&vst->q_video, &packet);
216
        else if( (packet.stream_index == vst->aStream) &&
217
                  (vst->has_sound != 0) )
6144 serge 218
        {
4438 Serge 219
            put_packet(&vst->q_audio, &packet);
6117 serge 220
            if(vst->audio_timer_valid == 0 &&
6144 serge 221
               packet.pts != AV_NOPTS_VALUE )
222
            {
4438 Serge 223
                vst->audio_timer_base = get_audio_base(vst) * packet.pts;
6144 serge 224
                vst->audio_timer_valid = 1;
225
            };
4438 Serge 226
        }
227
        else av_free_packet(&packet);
228
    }
229
    else if (err != AVERROR_EOF)
230
        printf("av_read_frame: error %x\n", err);
231
232
 
233
}
234
235
 
236
 
237
 
6117 serge 238
{
4438 Serge 239
    int err = 0;
240
    AVPacket  packet;
241
242
 
6117 serge 243
        err = load_frame(vst);
244
4438 Serge 245
 
246
};
247
248
 
249
 
6117 serge 250
{
4438 Serge 251
    AVPacket  packet;
252
253
 
6117 serge 254
    avcodec_flush_buffers(vst->aCtx);
255
    while( get_packet(&vst->q_video, &packet) != 0)
256
        av_free_packet(&packet);
4438 Serge 257
258
 
6117 serge 259
        av_free_packet(&packet);
4438 Serge 260
261
 
6118 serge 262
4438 Serge 263
 
264
};
265
266
 
6117 serge 267
{
4438 Serge 268
    int       eof;
269
    AVPacket  packet;
270
    int       ret, vret, aret;
271
272
 
273
274
 
5592 serge 275
276
 
4438 Serge 277
    {
278
        int err;
279
280
 
281
        {
282
            case PREPARE:
283
                eof = fill_queue(vst);
6117 serge 284
4438 Serge 285
 
286
                {
287
                    if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 288
                        (eof == 0) )
4438 Serge 289
                    {
290
                        eof = load_frame(vst);
6117 serge 291
                    }
4438 Serge 292
                    decode_video(vst);
6117 serge 293
                    ret = decode_audio(vst->aCtx, &vst->q_audio);
294
                }while(astream.count < resampler_size*2 && ret == 1);
6133 serge 295
4438 Serge 296
 
297
                decoder_state = PLAY;
298
                player_state  = PLAY;
299
300
 
301
                if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 302
                    (eof == 0) )
4438 Serge 303
                {
304
                    eof = load_frame(vst);
6117 serge 305
                }
4438 Serge 306
                vret = decode_video(vst);
6117 serge 307
                aret = decode_audio(vst->aCtx, &vst->q_audio);
308
                ret = vret | aret;
4438 Serge 309
310
 
311
                {
312
                    decoder_state = STOP;
313
                    continue;
314
                };
315
316
 
317
                {
318
                    if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 319
                        (eof == 0) )
4438 Serge 320
                    {
321
                        eof = load_frame(vst);
6117 serge 322
                        yield();
4438 Serge 323
                        continue;
324
                    };
325
                    delay(1);
326
                    continue;
327
                }
328
                yield();
329
                continue;
330
331
 
332
                delay(1);
333
                continue;
334
335
 
336
 
337
                while(sound_state != STOP)
338
                    delay(1);
339
340
 
6117 serge 341
4438 Serge 342
 
6117 serge 343
                    rewind_pos = vst->fCtx->start_time;
344
                else
4438 Serge 345
                    rewind_pos = 0;
346
347
 
6117 serge 348
                                         rewind_pos, INT64_MAX, 0);
4438 Serge 349
350
 
351
                continue;
6301 serge 352
4438 Serge 353
 
354
                while(sound_state != STOP)
355
                    yield();
356
357
 
6117 serge 358
                int opts = 0;
4438 Serge 359
                if(rewind_pos < 0)
360
                {
361
                    rewind_pos = -rewind_pos;
362
                    opts = AVSEEK_FLAG_BACKWARD;
363
                };
364
365
 
6117 serge 366
                    rewind_pos += vst->fCtx->start_time;
367
4438 Serge 368
 
369
                min_pos = rewind_pos - 1000000;
370
                max_pos = rewind_pos + 1000000;
371
372
 
6117 serge 373
                                         rewind_pos, INT64_MAX, 0);
4438 Serge 374
                if (ret < 0)
375
                {
376
                    printf("could not seek to position %f\n",
377
                            (double)rewind_pos / AV_TIME_BASE);
378
                }
379
                decoder_state = PREPARE;
380
                continue;
6301 serge 381
        }
4438 Serge 382
    };
383
};
384