Subversion Repositories Kolibri OS

Rev

Rev 6106 | Rev 6118 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6106 Rev 6117
Line 23... Line 23...
23
 
23
 
Line 24... Line 24...
24
void decoder();
24
void decoder();
25
int fplay_init_context(AVCodecContext *avctx);
25
int fplay_init_context(AVCodecContext *avctx);
Line 26... Line -...
26
 
-
 
27
AVFormatContext *pFormatCtx;
-
 
28
AVCodecContext  *pCodecCtx;
-
 
29
AVCodecContext  *aCodecCtx;
-
 
30
AVCodec         *pCodec;
-
 
31
AVCodec         *aCodec;
26
 
32
AVFrame         *pFrame;
-
 
33
int             videoStream;
-
 
Line 34... Line 27...
34
int             audioStream;
27
AVFrame         *pFrame;
Line 35... Line 28...
35
 
28
 
36
int             have_sound = 0;
29
int             have_sound = 0;
Line 42... Line 35...
42
char *movie_file;
35
char *movie_file;
43
 
36
 
Line 44... Line 37...
44
void flush_video();
37
void flush_video();
Line 45... Line -...
45
 
-
 
46
queue_t  q_video;
-
 
-
 
38
 
47
queue_t  q_audio;
39
 
Line 48... Line 40...
48
int64_t  rewind_pos;
40
int64_t  rewind_pos;
Line 49... Line 41...
49
 
41
 
Line 50... Line 42...
50
int64_t stream_duration;
42
int64_t stream_duration;
Line -... Line 43...
-
 
43
 
51
 
44
int threads_running = DECODER_THREAD;
52
int threads_running = DECODER_THREAD;
45
 
53
 
46
extern double audio_base;
54
extern double audio_base;
47
 
Line 55... Line 48...
55
 
48
 
56
double get_audio_base()
49
double get_audio_base(vst_t* vst)
-
 
50
{
57
{
51
    return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000;
58
  return (double)av_q2d(pFormatCtx->streams[audioStream]->time_base)*1000;
52
};
Line 59... Line 53...
59
};
53
 
60
 
54
 
61
 
55
int main( int argc, char *argv[])
Line 82... Line 76...
82
    avcodec_register_all();
76
    avcodec_register_all();
83
    avdevice_register_all();
77
    avdevice_register_all();
84
    av_register_all();
78
    av_register_all();
Line 85... Line 79...
85
 
79
 
86
    if( avformat_open_input(&pFormatCtx, movie_file, NULL, NULL) < 0)
80
    if( avformat_open_input(&vst.fCtx, movie_file, NULL, NULL) < 0)
87
    {
81
    {
88
        printf("Cannot open file %s\n\r", movie_file);
82
        printf("Cannot open file %s\n\r", movie_file);
89
        return -1; // Couldn't open file
83
        return -1; // Couldn't open file
Line 90... Line 84...
90
    };
84
    };
Line 91... Line 85...
91
 
85
 
92
    pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
86
    vst.fCtx->flags |= AVFMT_FLAG_GENPTS;
93
 
87
 
94
  // Retrieve stream information
88
  // Retrieve stream information
95
    if(avformat_find_stream_info(pFormatCtx, NULL)<0)
89
    if(avformat_find_stream_info(vst.fCtx, NULL) < 0)
96
    {
90
    {
Line 107... Line 101...
107
        movie_file[dot-file_name] = 0;
101
        movie_file[dot-file_name] = 0;
108
    }
102
    }
109
    else movie_file = file_name;
103
    else movie_file = file_name;
110
 
104
 
Line 111... Line 105...
111
    stream_duration = pFormatCtx->duration;
105
    stream_duration = vst.fCtx->duration;
Line 112... Line 106...
112
 
106
 
113
   // Find the first video stream
107
   // Find the first video stream
114
    videoStream=-1;
108
    vst.vStream = -1;
-
 
109
    vst.aStream = -1;
115
    audioStream=-1;
110
 
116
    for(i=0; i < pFormatCtx->nb_streams; i++)
111
    for(i=0; i < vst.fCtx->nb_streams; i++)
117
    {
112
    {
118
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
113
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
119
            && videoStream < 0)
114
            && vst.vStream < 0)
120
        {
115
        {
121
            videoStream=i;
116
            vst.vStream = i;
122
            video_time_base = pFormatCtx->streams[i]->time_base;
117
            video_time_base = vst.fCtx->streams[i]->time_base;
123
            if(stream_duration == 0)
118
            if(stream_duration == 0)
124
               stream_duration = pFormatCtx->streams[i]->duration;
-
 
125
 
119
               stream_duration = vst.fCtx->streams[i]->duration;
-
 
120
        }
126
        }
121
 
127
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
122
        if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
128
            audioStream < 0)
123
           vst.aStream < 0)
129
        {
124
        {
130
            audioStream=i;
125
            vst.aStream = i;
131
            if(stream_duration == 0)
126
            if(stream_duration == 0)
132
               stream_duration = pFormatCtx->streams[i]->duration;
127
               stream_duration = vst.fCtx->streams[i]->duration;
133
        }
128
        }
Line 134... Line 129...
134
    }
129
    }
135
 
130
 
136
    if(videoStream==-1)
131
    if(vst.vStream==-1)
137
    {
132
    {
138
        printf("Video stream not detected\n\r");
133
        printf("Video stream not detected\n\r");
Line 139... Line 134...
139
        return -1; // Didn't find a video stream
134
        return -1; // Didn't find a video stream
Line 140... Line 135...
140
    };
135
    };
141
 
136
 
142
  //   __asm__ __volatile__("int3");
137
  //   __asm__ __volatile__("int3");
143
 
-
 
144
    // Get a pointer to the codec context for the video stream
-
 
145
    pCodecCtx = pFormatCtx->streams[videoStream]->codec;
-
 
146
    aCodecCtx = pFormatCtx->streams[audioStream]->codec;
-
 
147
 
-
 
Line -... Line 138...
-
 
138
 
-
 
139
    // Get a pointer to the codec context for the video stream
148
  // Find the decoder for the video stream
140
    vst.vCtx = vst.fCtx->streams[vst.vStream]->codec;
Line 149... Line 141...
149
 
141
    vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
-
 
142
 
150
 
143
    vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id);
151
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
144
    printf("codec id %x name %s\n",vst.vCtx->codec_id, vst.vCodec->name);
152
 
145
    printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt);
153
//    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
146
 
Line -... Line 147...
-
 
147
    if(vst.vCodec == NULL)
-
 
148
    {
-
 
149
        printf("Unsupported codec with id %d for input stream %d\n",
154
 
150
        vst.vCtx->codec_id, vst.vStream);
155
    if(pCodec==NULL) {
151
        return -1; // Codec not found
156
        printf("Unsupported codec with id %d for input stream %d\n",
152
    }
157
        pCodecCtx->codec_id, videoStream);
153
 
158
        return -1; // Codec not found
154
 
159
    }
155
 
Line 160... Line -...
160
 
-
 
Line 161... Line 156...
161
    if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
156
 
162
    {
157
    if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0)
-
 
158
    {
Line 163... Line 159...
163
        printf("Error while opening codec for input stream %d\n",
159
        printf("Error while opening codec for input stream %d\n",
164
                videoStream);
160
                vst.vStream);
165
        return -1; // Could not open codec
161
        return -1; // Could not open codec
166
    };
162
    };
Line 167... Line 163...
167
 
163
 
Line 168... Line 164...
168
//    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
164
 
169
 
165
    mutex_init(&vst.q_video.lock);
170
    mutex_init(&q_video.lock);
166
    mutex_init(&vst.q_audio.lock);
171
    mutex_init(&q_audio.lock);
167
    mutex_init(&vst.gpu_lock);
172
 
168
 
173
    if (aCodecCtx->channels > 0)
169
    if (vst.aCtx->channels > 0)
174
            aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels);
170
        vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels);
Line 175... Line 171...
175
    else
171
    else
176
            aCodecCtx->request_channels = 2;
172
        vst.aCtx->request_channels = 2;
177
 
173
 
178
    aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
174
    vst.aCodec = avcodec_find_decoder(vst.aCtx->codec_id);
179
 
175
 
180
    if(aCodec)
176
    if(vst.aCodec)
181
    {
177
    {
182
        if(avcodec_open2(aCodecCtx, aCodec, NULL) >= 0 )
178
        if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 )
Line 183... Line 179...
183
        {
179
        {
Line 184... Line 180...
184
            WAVEHEADER       whdr;
180
            WAVEHEADER       whdr;
Line 185... Line 181...
185
            int fmt;
181
            int fmt;
186
            int channels;
182
            int channels;
Line 220... Line 216...
220
        else printf("Cannot open audio codec\n\r");
216
        else printf("Cannot open audio codec\n\r");
221
    }
217
    }
222
    else printf("Unsupported audio codec!\n");
218
    else printf("Unsupported audio codec!\n");
223
 
219
 
Line 224... Line 220...
224
    if( !init_video(pCodecCtx))
220
    if(!init_video(&vst))
225
        return 0;
221
        return 0;
Line 226... Line 222...
226
 
222
 
Line 227... Line 223...
227
    decoder();
223
    decoder(&vst);
228
 
224
 
Line 238... Line 234...
238
 
234
 
Line 239... Line 235...
239
    if(astream.lock.handle)
235
    if(astream.lock.handle)
240
        mutex_destroy(&astream.lock);
236
        mutex_destroy(&astream.lock);
Line 241... Line 237...
241
 
237
 
242
    mutex_destroy(&q_video.lock);
238
    mutex_destroy(&vst.q_video.lock);
Line 243... Line 239...
243
    mutex_destroy(&q_audio.lock);
239
    mutex_destroy(&vst.q_audio.lock);
244
 
240
 
Line 245... Line 241...
245
    return 0;
241
    return 0;
246
}
242
}
247
 
243
 
248
 
244
 
Line 249... Line 245...
249
static int load_frame()
245
static int load_frame(vst_t *vst)
250
{
246
{
251
    AVPacket  packet;
247
    AVPacket  packet;
252
    int err;
248
    int err;
253
 
249
 
254
    err = av_read_frame(pFormatCtx, &packet);
250
    err = av_read_frame(vst->fCtx, &packet);
255
    if( err == 0)
251
    if( err == 0)
256
    {
252
    {
257
        if(packet.stream_index==videoStream)
253
        if(packet.stream_index == vst->vStream)
258
            put_packet(&q_video, &packet);
254
            put_packet(&vst->q_video, &packet);
259
        else if( (packet.stream_index == audioStream) &&
255
        else if( (packet.stream_index == vst->aStream) &&
260
                  (have_sound != 0) )
256
                  (have_sound != 0) )
261
        {
257
        {
262
            put_packet(&q_audio, &packet);
258
            put_packet(&vst->q_audio, &packet);
263
            if(audio_base == -1.0)
259
            if(audio_base == -1.0)
264
            {
260
            {
265
                if (packet.pts != AV_NOPTS_VALUE)
261
                if (packet.pts != AV_NOPTS_VALUE)
266
                    audio_base = get_audio_base() * packet.pts;
262
                    audio_base = get_audio_base(vst) * packet.pts;
Line 276... Line 272...
276
}
272
}
277
 
273
 
Line 278... Line 274...
278
 
274
 
279
 
275
 
280
static int fill_queue()
276
static int fill_queue(vst_t* vst)
281
{
277
{
Line 282... Line 278...
282
    int err = 0;
278
    int err = 0;
283
    AVPacket  packet;
-
 
284
 
279
    AVPacket  packet;
Line 285... Line 280...
285
    while( (q_video.size < 4*1024*1024) &&
280
 
286
            !err )
-
 
287
        err = load_frame();
281
    while( (vst->q_video.size < 4*1024*1024) && !err )
Line 288... Line 282...
288
 
282
        err = load_frame(vst);
289
    return err;
283
 
290
 
284
    return err;
Line 291... Line 285...
291
};
285
};
292
 
286
 
293
 
287
 
294
static void flush_all()
288
static void flush_all(vst_t* vst)
Line 295... Line 289...
295
{
289
{
296
    AVPacket  packet;
290
    AVPacket  packet;
Line 297... Line 291...
297
 
291
 
Line 298... Line 292...
298
    avcodec_flush_buffers(pCodecCtx);
292
    avcodec_flush_buffers(vst->vCtx);
299
    avcodec_flush_buffers(aCodecCtx);
293
    avcodec_flush_buffers(vst->aCtx);
Line 300... Line 294...
300
    while( get_packet(&q_video, &packet) != 0)
294
    while( get_packet(&vst->q_video, &packet) != 0)
301
        av_free_packet(&packet);
295
        av_free_packet(&packet);
302
 
296
 
303
    while( get_packet(&q_audio, &packet)!= 0)
297
    while( get_packet(&vst->q_audio, &packet)!= 0)
304
        av_free_packet(&packet);
298
        av_free_packet(&packet);
Line 324... Line 318...
324
 
318
 
Line 325... Line 319...
325
        switch(decoder_state)
319
        switch(decoder_state)
326
        {
320
        {
327
            case PREPARE:
321
            case PREPARE:
328
                eof = fill_queue();
322
                eof = fill_queue(vst);
Line 329... Line 323...
329
 
323
 
330
                do
324
                do
331
                {
325
                {
332
                    if( (q_video.size < 4*1024*1024) &&
326
                    if( (vst->q_video.size < 4*1024*1024) &&
333
                        (eof == 0) )
327
                        (eof == 0) )
334
                    {
328
                    {
335
                        eof = load_frame();
329
                        eof = load_frame(vst);
336
                    }
330
                    }
337
                    decode_video(pCodecCtx, &q_video);
331
                    decode_video(vst);
338
                    ret = decode_audio(aCodecCtx, &q_audio);
332
                    ret = decode_audio(vst->aCtx, &vst->q_audio);
339
                }while(astream.count < resampler_size*2 &&
333
                }while(astream.count < resampler_size*2 &&
Line 340... Line 334...
340
                       ret == 1);
334
                       ret == 1);
341
 
335
 
342
                sound_state   = PREPARE;
336
                sound_state   = PREPARE;
Line 343... Line 337...
343
                decoder_state = PLAY;
337
                decoder_state = PLAY;
344
                player_state  = PLAY;
338
                player_state  = PLAY;
345
 
339
 
346
            case PLAY:
340
            case PLAY:
347
                if( (q_video.size < 4*1024*1024) &&
341
                if( (vst->q_video.size < 4*1024*1024) &&
348
                    (eof == 0) )
342
                    (eof == 0) )
349
                {
343
                {
350
                    eof = load_frame();
344
                    eof = load_frame(vst);
351
                }
345
                }
Line 352... Line 346...
352
                vret = decode_video(pCodecCtx, &q_video);
346
                vret = decode_video(vst);
353
                aret = decode_audio(aCodecCtx, &q_audio);
347
                aret = decode_audio(vst->aCtx, &vst->q_audio);
354
                ret = vret | aret;
348
                ret = vret | aret;
355
 
349
 
356
                if( eof && !ret)
350
                if( eof && !ret)
Line 357... Line 351...
357
                {
351
                {
358
                    decoder_state = STOP;
352
                    decoder_state = STOP;
359
                    continue;
353
                    continue;
360
                };
354
                };
361
 
355
 
362
                if( (vret & aret) == -1)
356
                if( (vret & aret) == -1)
363
                {
357
                {
364
                    if( (q_video.size < 4*1024*1024) &&
358
                    if( (vst->q_video.size < 4*1024*1024) &&
365
                        (eof == 0) )
359
                        (eof == 0) )
366
                    {
360
                    {
367
                        eof = load_frame();
361
                        eof = load_frame(vst);
Line 383... Line 377...
383
            case PLAY_2_STOP:
377
            case PLAY_2_STOP:
384
                while(sound_state != STOP)
378
                while(sound_state != STOP)
385
                    delay(1);
379
                    delay(1);
Line 386... Line 380...
386
 
380
 
Line 387... Line 381...
387
                flush_all();
381
                flush_all(vst);
388
 
382
 
389
                if (pFormatCtx->start_time != AV_NOPTS_VALUE)
383
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
390
                    rewind_pos = pFormatCtx->start_time;
384
                    rewind_pos = vst->fCtx->start_time;
Line 391... Line 385...
391
                else
385
                else
392
                    rewind_pos = 0;
386
                    rewind_pos = 0;
Line 393... Line 387...
393
 
387
 
394
                ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
388
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
Line 395... Line 389...
395
                                         rewind_pos, INT64_MAX, 0);
389
                                         rewind_pos, INT64_MAX, 0);
396
 
390
 
397
                decoder_state = STOP;
391
                decoder_state = STOP;
Line 398... Line 392...
398
                break;
392
                break;
399
 
393
 
400
            case REWIND:
394
            case REWIND:
401
                while(sound_state != STOP)
395
                while(sound_state != STOP)
402
                    yield();
396
                    yield();
403
 
397
 
404
                flush_all();
398
                flush_all(vst);
Line 405... Line 399...
405
                int opts = 0;
399
                int opts = 0;
406
                if(rewind_pos < 0)
400
                if(rewind_pos < 0)
Line 407... Line 401...
407
                {
401
                {
408
                    rewind_pos = -rewind_pos;
402
                    rewind_pos = -rewind_pos;
409
                    opts = AVSEEK_FLAG_BACKWARD;
403
                    opts = AVSEEK_FLAG_BACKWARD;
Line 410... Line 404...
410
                };
404
                };
411
 
405
 
412
                if (pFormatCtx->start_time != AV_NOPTS_VALUE)
-
 
413
                    rewind_pos += pFormatCtx->start_time;
406
                if (vst->fCtx->start_time != AV_NOPTS_VALUE)
414
 
407
                    rewind_pos += vst->fCtx->start_time;
415
//                printf("rewind %8"PRId64"\n", rewind_pos);
408
 
416
                min_pos = rewind_pos - 1000000;
409
//                printf("rewind %8"PRId64"\n", rewind_pos);
417
                max_pos = rewind_pos + 1000000;
410
                min_pos = rewind_pos - 1000000;
418
 
-
 
419
                ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
-
 
420
                                         rewind_pos, INT64_MAX, 0);
411
                max_pos = rewind_pos + 1000000;
421
 
412
 
422
                if (ret < 0)
413
                ret = avformat_seek_file(vst->fCtx, -1, INT64_MIN,
423
                {
414
                                         rewind_pos, INT64_MAX, 0);
424
                    printf("could not seek to position %f\n",
-
 
425
                            (double)rewind_pos / AV_TIME_BASE);
415
                if (ret < 0)