Subversion Repositories Kolibri OS

Rev

Rev 3068 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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