Subversion Repositories Kolibri OS

Rev

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