Subversion Repositories Kolibri OS

Rev

Rev 6301 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6301 Rev 6658
1
#include 
1
#include 
2
 
2
 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include 
5
#include 
6
#include 
6
#include 
7
 
7
 
8
#include 
8
#include 
9
#include 
9
#include 
10
#include 
10
#include 
11
#include 
11
#include 
12
#include 
12
#include 
13
#include "winlib/winlib.h"
13
#include "winlib/winlib.h"
14
 
14
 
15
#include "sound.h"
15
#include "sound.h"
16
#include "fplay.h"
16
#include "fplay.h"
17
 
17
 
18
volatile enum player_state player_state  = STOP;
18
volatile enum player_state player_state  = STOP;
19
volatile enum player_state decoder_state = PREPARE;
19
volatile enum player_state decoder_state = PREPARE;
20
volatile enum player_state sound_state   = STOP;
20
volatile enum player_state sound_state   = STOP;
21
 
21
 
22
uint32_t win_width, win_height;
22
uint32_t win_width, win_height;
23
 
23
 
24
uint8_t  *decoder_buffer;
24
uint8_t  *decoder_buffer;
25
extern int resampler_size;
25
extern int resampler_size;
26
extern int sample_rate;
26
extern int sample_rate;
27
 
27
 
28
int64_t  rewind_pos;
28
int64_t  rewind_pos;
29
 
29
 
30
int64_t stream_duration;
30
int64_t stream_duration;
31
 
31
 
32
int threads_running = DECODER_THREAD;
32
volatile int threads_running = DECODER_THREAD;
33
 
-
 
34
 
33
 
35
int main( int argc, char *argv[])
34
int main( int argc, char *argv[])
36
{
35
{
37
    static vst_t vst;
36
    static vst_t vst;
38
    int i, ret;
37
    int i, ret;
39
    char *file_name, *dot;
38
    char *file_name, *dot;
40
 
39
 
41
    if(argc < 2)
40
    if(argc < 2)
42
    {
41
    {
43
        vst.input_file = get_moviefile();
42
        vst.input_file = get_moviefile();
44
        if(vst.input_file == NULL)
43
        if(vst.input_file == NULL)
45
        {
44
        {
46
            printf("Please provide a movie file\n");
45
            printf("Please provide a movie file\n");
47
            return -1;
46
            return -1;
48
        }
47
        }
49
    }
48
    }
50
    else vst.input_file = argv[1];
49
    else vst.input_file = argv[1];
51
 
50
 
52
    /* register all codecs, demux and protocols */
51
    /* register all codecs, demux and protocols */
53
 
52
 
54
    av_log_set_level(AV_LOG_FATAL);
53
    av_log_set_level(AV_LOG_FATAL);
55
 
54
 
56
    avcodec_register_all();
55
    avcodec_register_all();
57
    avdevice_register_all();
56
    avdevice_register_all();
58
    av_register_all();
57
    av_register_all();
59
 
58
 
60
    if( avformat_open_input(&vst.fCtx, vst.input_file, NULL, NULL) < 0)
59
    if( avformat_open_input(&vst.fCtx, vst.input_file, NULL, NULL) < 0)
61
    {
60
    {
62
        printf("Cannot open file %s\n\r", vst.input_file);
61
        printf("Cannot open file %s\n\r", vst.input_file);
63
        return -1; // Couldn't open file
62
        return -1; // Couldn't open file
64
    };
63
    };
65
 
64
 
66
    vst.fCtx->flags |= AVFMT_FLAG_GENPTS;
65
    vst.fCtx->flags |= AVFMT_FLAG_GENPTS;
67
 
66
 
68
    if(avformat_find_stream_info(vst.fCtx, NULL) < 0)
67
    if(avformat_find_stream_info(vst.fCtx, NULL) < 0)
69
    {
68
    {
70
        printf("Cannot find streams\n\r");
69
        printf("Cannot find streams\n\r");
71
        return -1;
70
        return -1;
72
    };
71
    };
73
 
72
 
74
    file_name = strrchr(vst.input_file,'/')+1;
73
    file_name = strrchr(vst.input_file,'/')+1;
75
    dot = strrchr(file_name,'.');
74
    dot = strrchr(file_name,'.');
76
    if(dot)
75
    if(dot)
77
    {
76
    {
78
        vst.input_name = malloc(dot-file_name+1);
77
        vst.input_name = malloc(dot-file_name+1);
79
        memcpy(vst.input_name, file_name, dot-file_name);
78
        memcpy(vst.input_name, file_name, dot-file_name);
80
        vst.input_name[dot-file_name] = 0;
79
        vst.input_name[dot-file_name] = 0;
81
    }
80
    }
82
    else vst.input_name = file_name;
81
    else vst.input_name = file_name;
83
 
82
 
84
    stream_duration = vst.fCtx->duration;
83
    stream_duration = vst.fCtx->duration;
85
 
84
 
86
    vst.vStream = -1;
85
    vst.vStream = -1;
87
    vst.aStream = -1;
86
    vst.aStream = -1;
88
 
87
 
89
    for(i=0; i < vst.fCtx->nb_streams; i++)
88
    for(i=0; i < vst.fCtx->nb_streams; i++)
90
    {
89
    {
91
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
90
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
92
            && vst.vStream < 0)
91
            && vst.vStream < 0)
93
        {
92
        {
94
            vst.vStream = i;
93
            vst.vStream = i;
95
            vst.video_time_base = vst.fCtx->streams[i]->time_base;
94
            vst.video_time_base = vst.fCtx->streams[i]->time_base;
96
            if(stream_duration == 0)
95
            if(stream_duration == 0)
97
               stream_duration = vst.fCtx->streams[i]->duration;
96
               stream_duration = vst.fCtx->streams[i]->duration;
98
        }
97
        }
99
 
98
 
100
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
99
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
101
           vst.aStream < 0)
100
           vst.aStream < 0)
102
        {
101
        {
103
            vst.aStream = i;
102
            vst.aStream = i;
104
            if(stream_duration == 0)
103
            if(stream_duration == 0)
105
               stream_duration = vst.fCtx->streams[i]->duration;
104
               stream_duration = vst.fCtx->streams[i]->duration;
106
        }
105
        }
107
    }
106
    }
108
 
107
 
109
    if(vst.vStream==-1)
108
    if(vst.vStream==-1)
110
    {
109
    {
111
        printf("Video stream not detected\n\r");
110
        printf("Video stream not detected\n\r");
112
        return -1; // Didn't find a video stream
111
        return -1; // Didn't find a video stream
113
    };
112
    };
114
 
113
 
115
  //   __asm__ __volatile__("int3");
-
 
116
 
114
 
117
    INIT_LIST_HEAD(&vst.input_list);
115
    INIT_LIST_HEAD(&vst.input_list);
118
    INIT_LIST_HEAD(&vst.output_list);
116
    INIT_LIST_HEAD(&vst.output_list);
119
    mutex_init(&vst.q_video.lock);
117
    mutex_init(&vst.q_video.lock);
120
    mutex_init(&vst.q_audio.lock);
118
    mutex_init(&vst.q_audio.lock);
121
    mutex_init(&vst.gpu_lock);
119
    mutex_init(&vst.gpu_lock);
122
    mutex_init(&vst.decoder_lock);
120
    mutex_init(&vst.decoder_lock);
123
    mutex_init(&vst.input_lock);
121
    mutex_init(&vst.input_lock);
124
    mutex_init(&vst.output_lock);
122
    mutex_init(&vst.output_lock);
125
 
123
 
126
    vst.vCtx = vst.fCtx->streams[vst.vStream]->codec;
124
    vst.vCtx = vst.fCtx->streams[vst.vStream]->codec;
127
    vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
125
    vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
128
 
126
 
-
 
127
//    __asm__ __volatile__("int3");
-
 
128
 
129
    if(init_video_decoder(&vst) != 0 )
129
    if(init_video_decoder(&vst) != 0 )
130
        return -1;
130
        return -1;
131
 
131
 
132
    vst.aCtx->request_channel_layout = AV_CH_LAYOUT_STEREO;
132
    vst.aCtx->request_channel_layout = AV_CH_LAYOUT_STEREO;
133
    vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id);
133
    vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id);
134
    if(vst.aCodec)
134
    if(vst.aCodec)
135
    {
135
    {
136
        if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 )
136
        if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 )
137
        {
137
        {
138
            WAVEHEADER       whdr;
138
            WAVEHEADER       whdr;
139
            int fmt;
139
            int fmt;
140
            int channels;
140
            int channels;
141
 
141
 
142
            printf("audio stream rate %d channels %d format %d\n",
142
            printf("audio stream rate %d channels %d format %d\n",
143
            vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt );
143
            vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt );
144
            whdr.riff_id = 0x46464952;
144
            whdr.riff_id = 0x46464952;
145
            whdr.riff_format = 0x45564157;
145
            whdr.riff_format = 0x45564157;
146
            whdr.wFormatTag = 0x01;
146
            whdr.wFormatTag = 0x01;
147
            whdr.nSamplesPerSec = vst.aCtx->sample_rate;
147
            whdr.nSamplesPerSec = vst.aCtx->sample_rate;
148
            whdr.nChannels = 2;
148
            whdr.nChannels = 2;
149
            whdr.wBitsPerSample = 16;
149
            whdr.wBitsPerSample = 16;
150
 
150
 
151
            sample_rate = vst.aCtx->sample_rate;
151
            sample_rate = vst.aCtx->sample_rate;
152
 
152
 
153
            vst.snd_format = test_wav(&whdr);
153
            vst.snd_format = test_wav(&whdr);
154
 
154
 
155
            if( init_audio(&vst) )
155
            if( init_audio(&vst) )
156
            {
156
            {
157
                decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
157
                decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
158
                if( decoder_buffer != NULL )
158
                if( decoder_buffer != NULL )
159
                {
159
                {
160
                    mutex_init(&astream.lock);
160
                    mutex_init(&astream.lock);
161
                    astream.count  = 0;
161
                    astream.count  = 0;
162
                    astream.buffer = (char *)av_mallocz(192000*3);
162
                    astream.buffer = (char *)av_mallocz(192000*3);
163
                    if( astream.buffer != NULL )
163
                    if( astream.buffer != NULL )
164
                        vst.has_sound = 1;
164
                        vst.has_sound = 1;
165
                    else
165
                    else
166
                        av_free(decoder_buffer);
166
                        av_free(decoder_buffer);
167
                }
167
                }
168
                if( vst.has_sound == 0)
168
                if( vst.has_sound == 0)
169
                {
169
                {
170
                        printf("Not enough memory for audio buffers\n");
170
                        printf("Not enough memory for audio buffers\n");
171
                }
171
                }
172
            }
172
            }
173
        }
173
        }
174
        else printf("Cannot open audio codec\n\r");
174
        else printf("Cannot open audio codec\n\r");
175
    }
175
    }
176
    else printf("Unsupported audio codec!\n");
176
    else printf("Unsupported audio codec!\n");
177
 
177
 
178
    mutex_lock(&vst.decoder_lock);
178
    mutex_lock(&vst.decoder_lock);
179
    create_thread(video_thread, &vst, 1024*1024);
179
    create_thread(video_thread, &vst, 1024*1024);
180
    if(mutex_lock_timeout(&vst.decoder_lock, 3000) == 0)
180
    if(mutex_lock_timeout(&vst.decoder_lock, 3000) == 0)
181
        return -1;
181
        return -1;
182
 
182
 
183
    decoder(&vst);
183
    decoder(&vst);
184
 
184
 
185
 
185
 
186
//__asm__ __volatile__("int3");
186
//__asm__ __volatile__("int3");
187
 
187
 
188
    while( threads_running &
188
    while( threads_running &
189
           (AUDIO_THREAD | VIDEO_THREAD))
189
           (AUDIO_THREAD | VIDEO_THREAD))
190
           delay(1);
190
           delay(1);
191
 
191
 
192
    if(astream.lock.handle)
192
    if(astream.lock.handle)
193
        mutex_destroy(&astream.lock);
193
        mutex_destroy(&astream.lock);
194
 
194
 
195
    fini_video_decoder(&vst);
195
    vst.decoder->fini(&vst);
-
 
196
    avcodec_close(vst.vCtx);
-
 
197
 
196
    mutex_destroy(&vst.q_video.lock);
198
    mutex_destroy(&vst.q_video.lock);
197
    mutex_destroy(&vst.q_audio.lock);
199
    mutex_destroy(&vst.q_audio.lock);
198
    mutex_destroy(&vst.decoder_lock);
200
    mutex_destroy(&vst.decoder_lock);
199
 
201
 
200
    return 0;
202
    return 0;
201
}
203
}
202
 
204
 
203
 
205
 
204
static int load_frame(vst_t *vst)
206
static int load_frame(vst_t *vst)
205
{
207
{
206
    AVPacket  packet;
208
    AVPacket  packet;
207
    int err;
209
    int err;
208
 
210
 
209
    err = av_read_frame(vst->fCtx, &packet);
211
    err = av_read_frame(vst->fCtx, &packet);
210
    if( err == 0)
212
    if( err == 0)
211
    {
213
    {
212
        if(packet.stream_index == vst->vStream)
214
        if(packet.stream_index == vst->vStream)
213
            put_packet(&vst->q_video, &packet);
215
            put_packet(&vst->q_video, &packet);
214
        else if( (packet.stream_index == vst->aStream) &&
216
        else if( (packet.stream_index == vst->aStream) &&
215
                  (vst->has_sound != 0) )
217
                  (vst->has_sound != 0) )
216
        {
218
        {
217
            put_packet(&vst->q_audio, &packet);
219
            put_packet(&vst->q_audio, &packet);
218
            if(vst->audio_timer_valid == 0 &&
220
            if(vst->audio_timer_valid == 0 &&
219
               packet.pts != AV_NOPTS_VALUE )
221
               packet.pts != AV_NOPTS_VALUE )
220
            {
222
            {
221
                vst->audio_timer_base = get_audio_base(vst) * packet.pts;
223
                vst->audio_timer_base = get_audio_base(vst) * packet.pts;
222
                vst->audio_timer_valid = 1;
224
                vst->audio_timer_valid = 1;
223
            };
225
            };
224
        }
226
        }
225
        else av_free_packet(&packet);
227
        else av_free_packet(&packet);
226
    }
228
    }
227
    else if (err != AVERROR_EOF)
229
    else if (err != AVERROR_EOF)
228
        printf("av_read_frame: error %x\n", err);
230
        printf("av_read_frame: error %x\n", err);
229
 
231
 
230
    return err;
232
    return err;
231
}
233
}
232
 
234
 
233
 
235
 
234
 
236
 
235
static int fill_queue(vst_t* vst)
237
static int fill_queue(vst_t* vst)
236
{
238
{
237
    int err = 0;
239
    int err = 0;
238
    AVPacket  packet;
240
    AVPacket  packet;
239
 
241
 
240
    while( (vst->q_video.size < 4*1024*1024) && !err )
242
    while( (vst->q_video.size < 4*1024*1024) && !err )
241
        err = load_frame(vst);
243
        err = load_frame(vst);
242
 
244
 
243
    return err;
245
    return err;
244
};
246
};
245
 
247
 
246
 
248
 
247
static void flush_all(vst_t* vst)
249
static void flush_all(vst_t* vst)
248
{
250
{
249
    AVPacket  packet;
251
    AVPacket  packet;
250
 
252
 
251
    avcodec_flush_buffers(vst->vCtx);
253
    avcodec_flush_buffers(vst->vCtx);
252
    avcodec_flush_buffers(vst->aCtx);
254
    avcodec_flush_buffers(vst->aCtx);
253
    while( get_packet(&vst->q_video, &packet) != 0)
255
    while( get_packet(&vst->q_video, &packet) != 0)
254
        av_free_packet(&packet);
256
        av_free_packet(&packet);
255
 
257
 
256
    while( get_packet(&vst->q_audio, &packet)!= 0)
258
    while( get_packet(&vst->q_audio, &packet)!= 0)
257
        av_free_packet(&packet);
259
        av_free_packet(&packet);
258
 
260
 
259
    flush_video(vst);
261
    flush_video(vst);
260
 
262
 
261
    astream.count = 0;
263
    astream.count = 0;
262
};
264
};
263
 
265
 
264
void decoder(vst_t* vst)
266
void decoder(vst_t* vst)
265
{
267
{
266
    int       eof;
268
    int       eof;
267
    AVPacket  packet;
269
    AVPacket  packet;
268
    int       ret, vret, aret;
270
    int       ret, vret, aret;
269
 
271
 
270
    int64_t   min_pos, max_pos;
272
    int64_t   min_pos, max_pos;
271
 
273
 
272
//    av_log_set_level(AV_LOG_DEBUG);
274
//    av_log_set_level(AV_LOG_DEBUG);
273
 
275
 
274
    while( player_state != CLOSED )
276
    while( player_state != CLOSED )
275
    {
277
    {
276
        int err;
278
        int err;
277
 
279
 
278
        switch(decoder_state)
280
        switch(decoder_state)
279
        {
281
        {
280
            case PREPARE:
282
            case PREPARE:
281
                eof = fill_queue(vst);
283
                eof = fill_queue(vst);
282
 
284
 
283
                do
285
                do
284
                {
286
                {
285
                    if( (vst->q_video.size < 4*1024*1024) &&
287
                    if( (vst->q_video.size < 4*1024*1024) &&
286
                        (eof == 0) )
288
                        (eof == 0) )
287
                    {
289
                    {
288
                        eof = load_frame(vst);
290
                        eof = load_frame(vst);
289
                    }
291
                    }
290
                    decode_video(vst);
292
                    decode_video(vst);
291
                    ret = decode_audio(vst->aCtx, &vst->q_audio);
293
                    ret = decode_audio(vst->aCtx, &vst->q_audio);
292
                }while(astream.count < resampler_size*2 && ret == 1);
294
                }while(astream.count < resampler_size*2 && ret == 1);
293
 
295
 
294
                sound_state   = PREPARE;
296
                sound_state   = PREPARE;
295
                decoder_state = PLAY;
297
                decoder_state = PLAY;
296
                player_state  = PLAY;
298
                player_state  = PLAY;
297
 
299
 
298
            case PLAY:
300
            case PLAY:
299
                if( (vst->q_video.size < 4*1024*1024) &&
301
                if( (vst->q_video.size < 4*1024*1024) &&
300
                    (eof == 0) )
302
                    (eof == 0) )
301
                {
303
                {
302
                    eof = load_frame(vst);
304
                    eof = load_frame(vst);
303
                }
305
                }
304
                vret = decode_video(vst);
306
                vret = decode_video(vst);
305
                aret = decode_audio(vst->aCtx, &vst->q_audio);
307
                aret = decode_audio(vst->aCtx, &vst->q_audio);
306
                ret = vret | aret;
308
                ret = vret | aret;
307
 
309
 
308
                if( eof && !ret)
310
                if( eof && !ret)
309
                {
311
                {
310
                    decoder_state = STOP;
312
                    decoder_state = STOP;
311
                    continue;
313
                    continue;
312
                };
314
                };
313
 
315
 
314
                if( (vret & aret) == -1)
316
                if( (vret & aret) == -1)
315
                {
317
                {
316
                    if( (vst->q_video.size < 4*1024*1024) &&
318
                    if( (vst->q_video.size < 4*1024*1024) &&
317
                        (eof == 0) )
319
                        (eof == 0) )
318
                    {
320
                    {
319
                        eof = load_frame(vst);
321
                        eof = load_frame(vst);
320
                        yield();
322
                        yield();
321
                        continue;
323
                        continue;
322
                    };
324
                    };
323
                    delay(1);
325
                    delay(1);
324
                    continue;
326
                    continue;
325
                }
327
                }
326
                yield();
328
                yield();
327
                continue;
329
                continue;
328
 
330
 
329
            case STOP:
331
            case STOP:
330
                delay(1);
332
                delay(1);
331
                continue;
333
                continue;
332
 
334
 
333
 
335
 
334
            case PLAY_2_STOP:
336
            case PLAY_2_STOP:
335
                while(sound_state != STOP)
337
                while(sound_state != STOP)
336
                    delay(1);
338
                    delay(1);
337
 
339
 
338
                flush_all(vst);
340
                flush_all(vst);
339
 
341
 
340
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
342
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
341
                    rewind_pos = vst->fCtx->start_time;
343
                    rewind_pos = vst->fCtx->start_time;
342
                else
344
                else
343
                    rewind_pos = 0;
345
                    rewind_pos = 0;
344
 
346
 
345
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
347
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
346
                                         rewind_pos, INT64_MAX, 0);
348
                                         rewind_pos, INT64_MAX, 0);
347
 
349
 
348
                decoder_state = STOP;
350
                decoder_state = STOP;
349
                continue;
351
                continue;
350
 
352
 
351
            case REWIND:
353
            case REWIND:
352
                while(sound_state != STOP)
354
                while(sound_state != STOP)
353
                    yield();
355
                    yield();
354
 
356
 
355
                flush_all(vst);
357
                flush_all(vst);
356
                int opts = 0;
358
                int opts = 0;
357
                if(rewind_pos < 0)
359
                if(rewind_pos < 0)
358
                {
360
                {
359
                    rewind_pos = -rewind_pos;
361
                    rewind_pos = -rewind_pos;
360
                    opts = AVSEEK_FLAG_BACKWARD;
362
                    opts = AVSEEK_FLAG_BACKWARD;
361
                };
363
                };
362
 
364
 
363
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
365
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
364
                    rewind_pos += vst->fCtx->start_time;
366
                    rewind_pos += vst->fCtx->start_time;
365
 
367
 
366
//                printf("rewind %8"PRId64"\n", rewind_pos);
368
//                printf("rewind %8"PRId64"\n", rewind_pos);
367
                min_pos = rewind_pos - 1000000;
369
                min_pos = rewind_pos - 1000000;
368
                max_pos = rewind_pos + 1000000;
370
                max_pos = rewind_pos + 1000000;
369
 
371
 
370
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
372
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
371
                                         rewind_pos, INT64_MAX, 0);
373
                                         rewind_pos, INT64_MAX, 0);
372
                if (ret < 0)
374
                if (ret < 0)
373
                {
375
                {
374
                    printf("could not seek to position %f\n",
376
                    printf("could not seek to position %f\n",
375
                            (double)rewind_pos / AV_TIME_BASE);
377
                            (double)rewind_pos / AV_TIME_BASE);
376
                }
378
                }
377
                decoder_state = PREPARE;
379
                decoder_state = PREPARE;
378
                continue;
380
                continue;
379
        }
381
        }
380
    };
382
    };
381
};
383
};