Subversion Repositories Kolibri OS

Rev

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