Subversion Repositories Kolibri OS

Rev

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