Subversion Repositories Kolibri OS

Rev

Rev 6136 | Rev 6301 | 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
 
6121 serge 25
extern int resampler_size;
4438 Serge 26
extern int sample_rate;
27
28
 
29
30
 
31
32
 
5603 serge 33
34
 
4438 Serge 35
 
36
{
37
    static vst_t vst;
6117 serge 38
    int i, ret;
39
    char *file_name, *dot;
4438 Serge 40
41
 
42
    {
43
        vst.input_file = get_moviefile();
6136 serge 44
        if(vst.input_file == NULL)
45
        {
4438 Serge 46
            printf("Please provide a movie file\n");
47
            return -1;
48
        }
49
    }
50
    else vst.input_file = argv[1];
6136 serge 51
4438 Serge 52
 
53
54
 
55
56
 
57
    avdevice_register_all();
58
    av_register_all();
59
60
 
6136 serge 61
    {
4438 Serge 62
        printf("Cannot open file %s\n\r", vst.input_file);
6136 serge 63
        return -1; // Couldn't open file
4438 Serge 64
    };
65
66
 
6117 serge 67
4438 Serge 68
 
6117 serge 69
    {
4438 Serge 70
        printf("Cannot find streams\n\r");
71
        return -1;
72
    };
73
74
 
6136 serge 75
    dot = strrchr(file_name,'.');
4438 Serge 76
    if(dot)
77
    {
78
        vst.input_name = malloc(dot-file_name+1);
6136 serge 79
        memcpy(vst.input_name, file_name, dot-file_name);
80
        vst.input_name[dot-file_name] = 0;
81
    }
4438 Serge 82
    else vst.input_name = file_name;
6136 serge 83
4438 Serge 84
 
6117 serge 85
4438 Serge 86
 
6117 serge 87
    vst.aStream = -1;
88
89
 
90
    {
4438 Serge 91
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
6117 serge 92
            && vst.vStream < 0)
93
        {
4438 Serge 94
            vst.vStream = i;
6117 serge 95
            vst.video_time_base = vst.fCtx->streams[i]->time_base;
6136 serge 96
            if(stream_duration == 0)
4438 Serge 97
               stream_duration = vst.fCtx->streams[i]->duration;
6117 serge 98
        }
99
4438 Serge 100
 
6117 serge 101
           vst.aStream < 0)
102
        {
4438 Serge 103
            vst.aStream = i;
6117 serge 104
            if(stream_duration == 0)
4438 Serge 105
               stream_duration = vst.fCtx->streams[i]->duration;
6117 serge 106
        }
4438 Serge 107
    }
108
109
 
6117 serge 110
    {
4438 Serge 111
        printf("Video stream not detected\n\r");
112
        return -1; // Didn't find a video stream
113
    };
114
115
 
116
117
 
6133 serge 118
    INIT_LIST_HEAD(&vst.output_list);
119
    mutex_init(&vst.q_video.lock);
120
    mutex_init(&vst.q_audio.lock);
121
    mutex_init(&vst.gpu_lock);
122
    mutex_init(&vst.decoder_lock);
123
    mutex_init(&vst.input_lock);
124
    mutex_init(&vst.output_lock);
125
126
 
6144 serge 127
    vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
128
4438 Serge 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
 
154
155
 
156
            {
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
 
6144 serge 196
    mutex_destroy(&vst.q_video.lock);
6117 serge 197
    mutex_destroy(&vst.q_audio.lock);
198
    mutex_destroy(&vst.decoder_lock);
6133 serge 199
6144 serge 200
 
4438 Serge 201
}
202
203
 
204
 
6117 serge 205
{
4438 Serge 206
    AVPacket  packet;
207
    int err;
208
209
 
6117 serge 210
    if( err == 0)
4438 Serge 211
    {
212
        if(packet.stream_index == vst->vStream)
6117 serge 213
            put_packet(&vst->q_video, &packet);
214
        else if( (packet.stream_index == vst->aStream) &&
215
                  (vst->has_sound != 0) )
6144 serge 216
        {
4438 Serge 217
            put_packet(&vst->q_audio, &packet);
6117 serge 218
            if(vst->audio_timer_valid == 0 &&
6144 serge 219
               packet.pts != AV_NOPTS_VALUE )
220
            {
4438 Serge 221
                vst->audio_timer_base = get_audio_base(vst) * packet.pts;
6144 serge 222
                vst->audio_timer_valid = 1;
223
            };
4438 Serge 224
        }
225
        else av_free_packet(&packet);
226
    }
227
    else if (err != AVERROR_EOF)
228
        printf("av_read_frame: error %x\n", err);
229
230
 
231
}
232
233
 
234
 
235
 
6117 serge 236
{
4438 Serge 237
    int err = 0;
238
    AVPacket  packet;
239
240
 
6117 serge 241
        err = load_frame(vst);
242
4438 Serge 243
 
244
};
245
246
 
247
 
6117 serge 248
{
4438 Serge 249
    AVPacket  packet;
250
251
 
6117 serge 252
    avcodec_flush_buffers(vst->aCtx);
253
    while( get_packet(&vst->q_video, &packet) != 0)
254
        av_free_packet(&packet);
4438 Serge 255
256
 
6117 serge 257
        av_free_packet(&packet);
4438 Serge 258
259
 
6118 serge 260
4438 Serge 261
 
262
};
263
264
 
6117 serge 265
{
4438 Serge 266
    int       eof;
267
    AVPacket  packet;
268
    int       ret, vret, aret;
269
270
 
271
272
 
5592 serge 273
274
 
4438 Serge 275
    {
276
        int err;
277
278
 
279
        {
280
            case PREPARE:
281
                eof = fill_queue(vst);
6117 serge 282
4438 Serge 283
 
284
                {
285
                    if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 286
                        (eof == 0) )
4438 Serge 287
                    {
288
                        eof = load_frame(vst);
6117 serge 289
                    }
4438 Serge 290
                    decode_video(vst);
6117 serge 291
                    ret = decode_audio(vst->aCtx, &vst->q_audio);
292
                }while(astream.count < resampler_size*2 && ret == 1);
6133 serge 293
4438 Serge 294
 
295
                decoder_state = PLAY;
296
                player_state  = PLAY;
297
298
 
299
                if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 300
                    (eof == 0) )
4438 Serge 301
                {
302
                    eof = load_frame(vst);
6117 serge 303
                }
4438 Serge 304
                vret = decode_video(vst);
6117 serge 305
                aret = decode_audio(vst->aCtx, &vst->q_audio);
306
                ret = vret | aret;
4438 Serge 307
308
 
309
                {
310
                    decoder_state = STOP;
311
                    continue;
312
                };
313
314
 
315
                {
316
                    if( (vst->q_video.size < 4*1024*1024) &&
6117 serge 317
                        (eof == 0) )
4438 Serge 318
                    {
319
                        eof = load_frame(vst);
6117 serge 320
                        yield();
4438 Serge 321
                        continue;
322
                    };
323
                    delay(1);
324
                    continue;
325
                }
326
                yield();
327
                continue;
328
329
 
330
                delay(1);
331
                continue;
332
333
 
334
 
335
                while(sound_state != STOP)
336
                    delay(1);
337
338
 
6117 serge 339
4438 Serge 340
 
6117 serge 341
                    rewind_pos = vst->fCtx->start_time;
342
                else
4438 Serge 343
                    rewind_pos = 0;
344
345
 
6117 serge 346
                                         rewind_pos, INT64_MAX, 0);
4438 Serge 347
348
 
349
                break;
350
351
 
352
                while(sound_state != STOP)
353
                    yield();
354
355
 
6117 serge 356
                int opts = 0;
4438 Serge 357
                if(rewind_pos < 0)
358
                {
359
                    rewind_pos = -rewind_pos;
360
                    opts = AVSEEK_FLAG_BACKWARD;
361
                };
362
363
 
6117 serge 364
                    rewind_pos += vst->fCtx->start_time;
365
4438 Serge 366
 
367
                min_pos = rewind_pos - 1000000;
368
                max_pos = rewind_pos + 1000000;
369
370
 
6117 serge 371
                                         rewind_pos, INT64_MAX, 0);
4438 Serge 372
                if (ret < 0)
373
                {
374
                    printf("could not seek to position %f\n",
375
                            (double)rewind_pos / AV_TIME_BASE);
376
                }
377
                decoder_state = PREPARE;
378
                break;
379
        }
380
    };
381
};
382