Statistics
| Branch: | Revision:

chunker-player / chunker_player.c @ e810bf7b

History | View | Annotate | Download (29.8 KB)

1
// player.c
2
// Author 
3
// Diego Reforgiato, Dario Marchese, Carmelo Daniele
4
//
5
// Use the file compile to compile the program to build (assuming libavformat and libavcodec are 
6
// correctly installed your system).
7
//
8
// Run using
9
//
10
// player <width> <height>
11

    
12
#include <libavcodec/avcodec.h>
13
#include <libavformat/avformat.h>
14
#include <libswscale/swscale.h>
15

    
16
#include <stdio.h>
17
#include <dirent.h>
18
#include <string.h>
19
#include <stdlib.h>
20
#include <sys/time.h>
21
#include <unistd.h>
22
#include <signal.h>
23
#include <SDL.h>
24
#include <SDL_thread.h>
25
#include <SDL_mutex.h>
26

    
27
#ifdef __MINGW32__
28
#undef main /* Prevents SDL from overriding main() */
29
#endif
30

    
31
#include <platform.h>
32
#include <microhttpd.h>
33
//#include <AntTweakBar.h>
34

    
35
#include "chunker_player.h"
36
#include "codec_definitions.h"
37

    
38
#define SDL_AUDIO_BUFFER_SIZE 1024
39

    
40
#define QUEUE_FILLING_THRESHOLD        50
41
#define AUDIO        1
42
#define VIDEO        2
43

    
44
#define DEBUG_AUDIO
45
#define DEBUG_VIDEO
46
#define DEBUG_QUEUE
47
#define DEBUG_SOURCE
48

    
49
short int QueueFillingMode=1;
50
short int QueueStopped=0;
51

    
52
typedef struct PacketQueue {
53
        AVPacketList *first_pkt, *last_pkt;
54
        int nb_packets;
55
        int size;
56
        SDL_mutex *mutex;
57
        SDL_cond *cond;
58
        short int queueType;
59
        int last_frame_extracted;
60
        int total_lost_frames;
61
} PacketQueue;
62

    
63
typedef struct threadVal {
64
        int width;
65
        int height;
66
} ThreadVal;
67

    
68
int AudioQueueOffset=0;
69
PacketQueue audioq;
70
PacketQueue videoq;
71
AVPacket AudioPkt, VideoPkt;
72
int quit = 0;
73

    
74
SDL_Surface *screen;
75
SDL_Overlay *yuv_overlay;
76
SDL_Rect    rect;
77

    
78
int got_sigint = 0;
79

    
80
#define MAX_TOLLERANCE 60
81

    
82
long long DeltaTime;
83
short int FirstTimeAudio=1, FirstTimeVideo = 1, FirstTime = 1;
84

    
85
int dimAudioQ;
86
float deltaAudioQ;
87

    
88
void packet_queue_init(PacketQueue *q, short int Type) {
89
        memset(q,0,sizeof(PacketQueue));
90
        q->mutex = SDL_CreateMutex();
91
        q->cond = SDL_CreateCond();
92
        QueueFillingMode=1;
93
        q->queueType=Type;
94
        q->last_frame_extracted = 0;
95
        q->total_lost_frames = 0;
96
}
97

    
98
int packet_queue_put(PacketQueue *q, AVPacket *pkt) {
99
        short int skip = 0;
100
        AVPacketList *pkt1, *tmp, *prevtmp;
101
        if(av_dup_packet(pkt) < 0) {
102
                return -1;
103
        }
104
        pkt1 = av_malloc(sizeof(AVPacketList));
105
        if (!pkt1)
106
                return -1;
107
        pkt1->pkt = *pkt;
108
        pkt1->next = NULL;
109

    
110
        SDL_LockMutex(q->mutex);
111

    
112
// INSERTION SORT ALGORITHM
113
// before inserting pkt, check if pkt.stream_index is <= current_extracted_frame.
114

    
115
        if(pkt->stream_index>q->last_frame_extracted) {
116

    
117
// either checking starting from the first_pkt or needed other struct like AVPacketList with next and prev....
118
                if (!q->last_pkt)
119
                        q->first_pkt = pkt1;
120
                else {
121
                        tmp = q->first_pkt;
122
                        while(tmp->pkt.stream_index<pkt->stream_index) {
123
                                prevtmp = tmp;
124
                                tmp = tmp->next;
125
                                if(!tmp)
126
                                        break;
127
                        }
128
                        if(tmp && tmp->pkt.stream_index==pkt->stream_index) {
129
                                skip = 1;
130
                        }
131
                        else {
132
                                prevtmp->next = pkt1;
133
                                pkt1->next = tmp;
134
                        }
135
//                        q->last_pkt->next = pkt1; // It was uncommented when not insertion sort
136
                }
137
                if(skip==0) {
138
                        q->last_pkt = pkt1;
139
                        q->nb_packets++;
140
                        q->size += pkt1->pkt.size;
141
#ifdef DEBUG_QUEUE
142
                        printf("PUT in Queue: NPackets=%d Type=%d\n",q->nb_packets,q->queueType);
143
#endif
144

    
145
                        if(q->nb_packets>=QUEUE_FILLING_THRESHOLD && QueueFillingMode) // && q->queueType==AUDIO)
146
                        {
147
                                QueueFillingMode=0;
148
#ifdef DEBUG_QUEUE
149
                        printf("PUT in Queue: FillingMode set to zero\n");
150
#endif
151
                                //SDL_CondSignal(q->cond);
152
                        }
153
//WHYYYYYYYYY                        q->last_frame_extracted = pkt->stream_index;
154
//#ifdef DEBUG_QUEUE
155
//                        printf("PUT LastFrameExtracted set to %d\n",q->last_frame_extracted);
156
//#endif
157
                }
158
        }
159

    
160
        SDL_UnlockMutex(q->mutex);
161
        return 0;
162
}
163

    
164
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, short int av) {
165
        //AVPacket tmp;
166
        AVPacketList *pkt1;
167
        int ret=-1;
168
        int SizeToCopy=0;
169

    
170
#ifdef DEBUG_QUEUE
171
        printf("QUEUE Get NPackets=%d Type=%d\n",q->nb_packets,q->queueType);
172
#endif
173

    
174
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
175
        {
176
                return -1;
177
                //SDL_CondWait(q->cond, q->mutex);
178
        }
179

    
180
        SDL_LockMutex(q->mutex);
181
        pkt1 = q->first_pkt;
182
        if (pkt1) {
183
                if(av==1) {
184
                        if(pkt1->pkt.size-AudioQueueOffset>dimAudioQ) {
185
#ifdef DEBUG_QUEUE
186
                                printf("  AV=1 and Extract from the same packet\n");
187
#endif
188
                                //av_init_packet(&tmp);
189
                                q->size -= dimAudioQ;
190
                                pkt->size = dimAudioQ;
191
                                //tmp.data = pkt1->pkt.data+AudioQueueOffset;
192
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
193
                                pkt->dts = pkt1->pkt.dts;
194
                                pkt->pts = pkt1->pkt.pts;
195
                                pkt->stream_index = pkt1->pkt.stream_index;//1;
196
                                pkt->flags = 1;
197
                                pkt->pos = -1;
198
                                pkt->convergence_duration = -1;
199

    
200
                                //*pkt = tmp;
201
                                //pkt1->pkt.size -= dimAudioQ;
202
                                pkt1->pkt.dts += deltaAudioQ;
203
                                pkt1->pkt.pts += deltaAudioQ;
204
                                AudioQueueOffset += dimAudioQ;
205
#ifdef DEBUG_QUEUE
206
                                printf("   AudioQueueOffset = %d\n",AudioQueueOffset);
207
#endif
208
                                
209
                                ret = 1;
210
                                //compute lost frame statistics
211
                        if(q->last_frame_extracted > 0 && pkt->stream_index > q->last_frame_extracted) {
212
#ifdef DEBUG_QUEUE
213
                                        printf("  stats: stidx %d last %d tot %d\n", pkt->stream_index, q->last_frame_extracted, q->total_lost_frames);
214
#endif
215
                                        q->total_lost_frames = q->total_lost_frames + pkt->stream_index - q->last_frame_extracted - 1;
216
                                }
217
                                //update index of last frame extracted
218
                                q->last_frame_extracted = pkt->stream_index;
219
                        }
220
                        else {
221
#ifdef DEBUG_QUEUE
222
                                printf("  AV = 1 and Extract from 2 packets\n");
223
#endif
224
                                // Check for loss
225
                                if(pkt1->next)
226
                                {
227
#ifdef DEBUG_QUEUE
228
                                        printf("   we have a next...\n");
229
#endif
230
                                        //av_init_packet(&tmp);
231
                                        pkt->size = dimAudioQ;
232
                                        pkt->dts = pkt1->pkt.dts;
233
                                        pkt->pts = pkt1->pkt.pts;
234
                                        pkt->stream_index = pkt1->pkt.stream_index;//1;
235
                                        pkt->flags = 1;
236
                                        pkt->pos = -1;
237
                                        pkt->convergence_duration = -1;
238
                                        //tmp.data = (uint8_t *)malloc(sizeof(uint8_t)*dimAudioQ);
239
                                        //if(tmp.data)
240
                                        {
241
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
242
#ifdef DEBUG_QUEUE
243
                                                printf("      SizeToCopy=%d\n",SizeToCopy);
244
#endif
245
                                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,SizeToCopy);
246
                                                memcpy(pkt->data+SizeToCopy,pkt1->next->pkt.data,(dimAudioQ-SizeToCopy)*sizeof(uint8_t));
247
                                        }
248
                                        //*pkt = tmp;
249
                                }
250
                                q->first_pkt = pkt1->next;
251
                                if (!q->first_pkt)
252
                                        q->last_pkt = NULL;
253
                                q->nb_packets--;
254
                                q->size -= SizeToCopy;
255
#ifdef DEBUG_QUEUE
256
                                printf("  about to free... ");
257
#endif
258
                                free(pkt1->pkt.data);
259
                                av_free(pkt1);
260
#ifdef DEBUG_QUEUE
261
                                printf("freeed\n");
262
#endif
263
                                // Adjust timestamps
264
                                pkt1 = q->first_pkt;
265
                                if(pkt1)
266
                                {
267
                                        pkt1->pkt.dts = pkt->dts + deltaAudioQ;
268
                                        pkt1->pkt.pts = pkt->pts + deltaAudioQ;
269
                                        AudioQueueOffset=dimAudioQ-SizeToCopy;
270
                                        q->size -= AudioQueueOffset;
271
                                        ret = 1;
272
                                }
273
                                else
274
                                {
275
                                        AudioQueueOffset=0;
276
                                }
277
#ifdef DEBUG_QUEUE
278
                                printf("   AudioQueueOffset = %d\n",AudioQueueOffset);
279
#endif
280

    
281
                                //compute lost frame statistics
282
                        if(q->last_frame_extracted > 0 && pkt->stream_index > q->last_frame_extracted) {
283
#ifdef DEBUG_QUEUE
284
                                        printf("  stats: stidx %d last %d tot %d\n", pkt->stream_index, q->last_frame_extracted, q->total_lost_frames);
285
#endif
286
                                        q->total_lost_frames = q->total_lost_frames + pkt->stream_index - q->last_frame_extracted - 1;
287
                                }
288
                                //update index of last frame extracted
289
                                q->last_frame_extracted = pkt->stream_index;
290
                        }
291
                }
292
                else {
293
#ifdef DEBUG_QUEUE
294
                                printf("  AV not 1\n");
295
#endif
296
                        q->first_pkt = pkt1->next;
297
                        if (!q->first_pkt)
298
                                q->last_pkt = NULL;
299
                        q->nb_packets--;
300
                        q->size -= pkt1->pkt.size;
301
                        
302
                        pkt->size = pkt1->pkt.size;
303
                        pkt->dts = pkt1->pkt.dts;
304
                        pkt->pts = pkt1->pkt.pts;
305
                        pkt->stream_index = pkt1->pkt.stream_index;
306
                        pkt->flags = pkt1->pkt.flags;
307
                        pkt->pos = pkt1->pkt.pos;
308
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
309
                        //*pkt = pkt1->pkt;
310
#ifdef DEBUG_QUEUE
311
                                printf("  about to free... ");
312
#endif
313
                        memcpy(pkt->data,pkt1->pkt.data,pkt1->pkt.size);
314
                        free(pkt1->pkt.data);
315
                        av_free(pkt1);
316
#ifdef DEBUG_QUEUE
317
                                printf("freeed\n");
318
#endif
319
                        ret = 1;
320
                        //compute lost frame statistics
321
                        if(q->last_frame_extracted > 0 && pkt->stream_index > q->last_frame_extracted) {
322
#ifdef DEBUG_QUEUE
323
                                        printf("  stats: stidx %d last %d tot %d\n", pkt->stream_index, q->last_frame_extracted, q->total_lost_frames);
324
#endif
325
                                        q->total_lost_frames = q->total_lost_frames + pkt->stream_index - q->last_frame_extracted - 1;
326
                        }
327
                        //update index of last frame extracted
328
                        q->last_frame_extracted = pkt->stream_index;
329
                }
330
        }
331
#ifdef DEBUG_QUEUE
332
        else {
333
                printf("  pk1 NULLLLLLLLLL!!!!\n");
334
        }
335
#endif
336

    
337
        if(q->nb_packets==0 && q->queueType==AUDIO) {
338
                QueueFillingMode=1;
339
#ifdef DEBUG_QUEUE
340
                printf("QUEUE Get FillingMode ON\n");
341
#endif
342
        }
343
#ifdef DEBUG_QUEUE
344
        printf("QUEUE Get LastFrameExtracted = %d\n",q->last_frame_extracted);
345
        printf("QUEUE Get Tot lost frames = %d\n",q->total_lost_frames);
346
#endif
347

    
348
        SDL_UnlockMutex(q->mutex);
349
        return ret;
350
}
351

    
352

    
353
int audio_decode_frame(uint8_t *audio_buf, int buf_size) {
354
        //struct timeval now;
355
        int audio_pkt_size = 0;
356
        long long Now;
357
        short int DecodeAudio=0, SkipAudio=0;
358
        //int len1, data_size;
359

    
360
        //gettimeofday(&now,NULL);
361
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
362
        Now=(long long)SDL_GetTicks();
363

    
364
        if(QueueFillingMode || QueueStopped)
365
        {
366
                FirstTimeAudio=1;
367
                FirstTime = 1;
368
                return -1;
369
        }
370

    
371
        if((FirstTime==1 || FirstTimeAudio==1) && audioq.size>0) {
372
                if(audioq.first_pkt->pkt.pts>0)
373
                {
374
                        DeltaTime=Now-(long long)(audioq.first_pkt->pkt.pts);
375
                        FirstTimeAudio = 0;
376
                        FirstTime = 0;
377
#ifdef DEBUG_AUDIO 
378
                         printf("audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTime);
379
#endif
380
                }
381
        }
382

    
383
#ifdef DEBUG_AUDIO 
384
        if(audioq.first_pkt)
385
        {
386
                printf("audio_decode_frame - Syncro params: DeltaNow-pts=%lld ",(Now-((long long)audioq.first_pkt->pkt.pts+DeltaTime)));
387
                printf("pts=%lld ",(long long)audioq.first_pkt->pkt.pts);
388
                printf("Tollerance=%d ",(int)MAX_TOLLERANCE);
389
                printf("QueueLen=%d ",(int)audioq.nb_packets);
390
                printf("QueueSize=%d\n",(int)audioq.size);
391
        }
392
        else
393
                printf("audio_decode_frame - Empty queue\n");
394
#endif
395

    
396

    
397
        if(audioq.nb_packets>0) {
398
                if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
399
                        SkipAudio = 1;
400
                        DecodeAudio = 0;
401
                }
402
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
403
                        (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
404
                                SkipAudio = 0;
405
                                DecodeAudio = 1;
406
                }
407
        }
408
                
409
        while(SkipAudio==1 && audioq.size>0) {
410
                SkipAudio = 0;
411
#ifdef DEBUG_AUDIO
412
                 printf("skipaudio: queue size=%d\n",audioq.size);
413
#endif
414
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
415
                        return -1;
416
                }
417
                if(audioq.first_pkt)
418
                {
419
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
420
                                SkipAudio = 1;
421
                                DecodeAudio = 0;
422
                        }
423
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
424
                                (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
425
                                        SkipAudio = 0;
426
                                        DecodeAudio = 1;
427
                        }
428
                }
429
        }
430
        if(DecodeAudio==1) {
431
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
432
                        return -1;
433
                }
434
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
435
                audio_pkt_size = AudioPkt.size;
436
#ifdef DEBUG_AUDIO
437
                 printf("Decode audio\n");
438
#endif
439
        }
440

    
441
        return audio_pkt_size;
442

    
443
}
444

    
445
/*static long get_time_diff(struct timeval time_now) {
446
        struct timeval time_now2;
447
        gettimeofday(&time_now2,0);
448
        return time_now2.tv_sec*1.e6 - time_now.tv_sec*1.e6 + time_now2.tv_usec - time_now.tv_usec;
449
}*/
450

    
451
int video_callback(void *valthread) {
452
        //AVPacket pktvideo;
453
        AVCodecContext  *pCodecCtx;
454
        AVCodec         *pCodec;
455
        AVFrame                *pFrame;
456
        AVPacket        packet;
457
        int                frameFinished;
458
        int                 countexit;
459
        AVPicture pict;
460
        static struct SwsContext *img_convert_ctx;
461
        //FILE *frecon;
462
        SDL_Event event;
463
        long long Now;
464
        short int SkipVideo, DecodeVideo;
465

    
466
        //double frame_rate = 0.0,time_between_frames=0.0;
467
        //struct timeval now;
468

    
469
        //int wait_for_sync = 1;
470
        ThreadVal *tval;
471
        tval = (ThreadVal *)valthread;
472

    
473
        //frame_rate = tval->framerate;
474
        //time_between_frames = 1.e6 / frame_rate;
475
        //gettimeofday(&time_now,0);
476

    
477
        //frecon = fopen("recondechunk.mpg","wb");
478

    
479
        pCodecCtx=avcodec_alloc_context();
480
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
481
#ifdef H264_VIDEO_ENCODER
482
        pCodecCtx->codec_id  = CODEC_ID_H264;
483
        pCodecCtx->me_range = 16;
484
        pCodecCtx->max_qdiff = 4;
485
        pCodecCtx->qmin = 10;
486
        pCodecCtx->qmax = 51;
487
        pCodecCtx->qcompress = 0.6;
488
#else
489
        pCodecCtx->codec_id  = CODEC_ID_MPEG4;
490
#endif
491
//pCodecCtx->bit_rate = 400000;
492
        // resolution must be a multiple of two
493
        pCodecCtx->width = tval->width;//176;//352;
494
        pCodecCtx->height = tval->height;//144;//288;
495
        // frames per second
496
//pCodecCtx->time_base = (AVRational){1,25};
497
//pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
498
//pCodecCtx->max_b_frames=1;
499
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
500
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
501

    
502
        if(pCodec==NULL) {
503
                fprintf(stderr, "Unsupported codec!\n");
504
                return -1; // Codec not found
505
        }
506
        if(avcodec_open(pCodecCtx, pCodec)<0) {
507
                fprintf(stderr, "could not open codec\n");
508
                return -1; // Could not open codec
509
        }
510
        pFrame=avcodec_alloc_frame();
511
        if(pFrame==NULL) {
512
                printf("Memory error!!!\n");
513
                return -1;
514
        }
515

    
516
        while(!quit) {
517
                if(QueueFillingMode || QueueStopped)
518
                {
519
                        FirstTime = 1;
520
                        usleep(5000);
521
                        continue;
522
                }
523

    
524
                DecodeVideo = 0;
525
                SkipVideo = 0;
526
                //gettimeofday(&now,NULL);
527
                //Now = (unsigned long long)now.tv_sec*1000+(unsigned long long)now.tv_usec/1000;
528
                Now=(long long)SDL_GetTicks();
529
                if(FirstTime==1 && videoq.size>0) {
530
                        if(videoq.first_pkt->pkt.pts>0)
531
                        {
532
                                DeltaTime=Now-(long long)videoq.first_pkt->pkt.pts;
533
                                FirstTime = 0;
534
                        }
535
#ifdef DEBUG_VIDEO 
536
                         printf("VideoCallback - DeltaTimeAudio=%lld\n",DeltaTime);
537
#endif
538
                }
539

    
540
#ifdef DEBUG_VIDEO 
541
                if(videoq.first_pkt)
542
                {
543
                        printf("VideoCallback - Syncro params: Delta:%lld Now:%lld pts=%lld ",(long long)DeltaTime,Now,(long long)videoq.first_pkt->pkt.pts);
544
                        printf("pts=%lld ",(long long)videoq.first_pkt->pkt.pts);
545
                        printf("Tollerance=%d ",(int)MAX_TOLLERANCE);
546
                        printf("QueueLen=%d ",(int)videoq.nb_packets);
547
                        printf("QueueSize=%d\n",(int)videoq.size);
548
                }
549
                else
550
                        printf("VideoCallback - Empty queue\n");
551
#endif
552

    
553
                if(videoq.nb_packets>0) {
554
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)<Now-(long long)MAX_TOLLERANCE) {
555
                                SkipVideo = 1;
556
                                DecodeVideo = 0;
557
                        }
558
                        else 
559
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)>=Now-(long long)MAX_TOLLERANCE &&
560
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTime)<=Now+(long long)MAX_TOLLERANCE) {
561
                                        SkipVideo = 0;
562
                                        DecodeVideo = 1;
563
                                }
564
                }
565
#ifdef DEBUG_VIDEO
566
                printf("skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
567
#endif
568

    
569
                while(SkipVideo==1 && videoq.size>0) {
570
                        SkipVideo = 0;
571
#ifdef DEBUG_VIDEO 
572
                         printf("Skip Video\n");
573
#endif
574
                        if(packet_queue_get(&videoq,&VideoPkt,0) < 0) {
575
                                break;
576
                        }
577
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
578
                        if(videoq.first_pkt)
579
                        {
580
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
581
                                        SkipVideo = 1;
582
                                        DecodeVideo = 0;
583
                                }
584
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
585
                                        (long long)videoq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
586
                                        SkipVideo = 0;
587
                                        DecodeVideo = 1;
588
                                }
589
                        }
590
                }
591
                
592
                if(DecodeVideo==1) {
593
                        if(packet_queue_get(&videoq,&VideoPkt,0) > 0) {
594

    
595
#ifdef DEBUG_VIDEO
596
                                printf("Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
597
#endif
598

    
599
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
600

    
601
                                if(frameFinished) { // it must be true all the time else error
602
#ifdef DEBUG_VIDEO
603
                                printf("FrameFinished\n");
604
#endif
605
                                        //SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height, cont++);
606
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
607

    
608
                                        // Lock SDL_yuv_overlay
609
                                        if ( SDL_MUSTLOCK(screen) ) {
610
#ifdef DEBUG_VIDEO
611
                                printf("-1 ");
612
#endif
613

    
614
                                                if ( SDL_LockSurface(screen) < 0 ) {
615
#ifdef DEBUG_VIDEO
616
                                printf("0 ");
617
#endif
618
                                                                                                                                break;
619
                                                                                                                        }
620
                                        }
621
#ifdef DEBUG_VIDEO
622
                                printf("1 ");
623
#endif
624
                                        if (SDL_LockYUVOverlay(yuv_overlay) < 0) break;
625
#ifdef DEBUG_VIDEO
626
                                printf("2 ");
627
#endif
628

    
629
                                        pict.data[0] = yuv_overlay->pixels[0];
630
                                        pict.data[1] = yuv_overlay->pixels[2];
631
                                        pict.data[2] = yuv_overlay->pixels[1];
632

    
633
                                        pict.linesize[0] = yuv_overlay->pitches[0];
634
                                        pict.linesize[1] = yuv_overlay->pitches[2];
635
                                        pict.linesize[2] = yuv_overlay->pitches[1];
636
#ifdef DEBUG_VIDEO
637
                                printf("3 ");
638
#endif
639

    
640
                                        img_convert_ctx = sws_getContext(tval->width,tval->height,PIX_FMT_YUV420P,tval->width,tval->height,PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);
641
#ifdef DEBUG_VIDEO
642
                                printf("4 ");
643
#endif
644

    
645
                                        if(img_convert_ctx==NULL) {
646
                                                fprintf(stderr,"Cannot initialize the conversion context!\n");
647
                                                exit(1);
648
                                        }
649
                                        sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,0,tval->height,pict.data,pict.linesize);
650
#ifdef DEBUG_VIDEO
651
                                printf("5 ");
652
#endif
653

    
654
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
655
                                        if ( SDL_MUSTLOCK(screen) ) {
656
                                                SDL_UnlockSurface(screen);
657
                                        }
658
#ifdef DEBUG_VIDEO
659
                                printf("6 ");
660
#endif
661

    
662
                                        SDL_UnlockYUVOverlay(yuv_overlay);
663

    
664
                                        // Show, baby, show!
665
                                        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
666
#ifdef DEBUG_VIDEO
667
                                printf("7\n");
668
#endif
669
                        
670
                                }
671
                        }
672
                }
673

    
674
                usleep(5000);
675

    
676
                /*SDL_PollEvent(&event);
677
                switch(event.type) {
678
                case SDL_QUIT:
679
                        quit=1;
680
                        //exit(0);
681
                        break;
682
                }*/
683
        }
684
        av_free(pCodecCtx);
685
        //fclose(frecon);
686
#ifdef DEBUG_VIDEO
687
         printf("video callback end\n");
688
#endif
689
        return 1;
690
}
691

    
692
/*int audio_decode_frame2(uint8_t *audio_buf,int len) {
693
        AVPacket pkt;
694
        if(packet_queue_get(&audioq, &pkt, 1,1) < 0) {
695
                return -1;
696
        }
697
        memcpy(audio_buf,pkt.data,pkt.size);
698
        //printf("tornato : %d bytes\n",pkt.size);
699
        return pkt.size;
700
}*/
701

    
702
void audio_callback(void *userdata, Uint8 *stream, int len) {
703

    
704
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
705
        int audio_size;
706

    
707
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
708

    
709
        audio_size = audio_decode_frame(audio_buf, sizeof(audio_buf));
710
        if(audio_size != len) {
711
                memset(stream, 0, len);
712
        } else {
713
                memcpy(stream, (uint8_t *)audio_buf, len);
714
        }
715
}
716

    
717
void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
718
        SDL_Surface *image;
719
        SDL_Rect dest;
720

    
721
        /* Load a BMP file on a surface */
722
        image = SDL_LoadBMP(file);
723
        if ( image == NULL ) {
724
                fprintf(stderr, "Error loading %s: %s\n", file, SDL_GetError());
725
                return;
726
        }
727

    
728
        /* Copy on the screen surface 
729
        surface should be blocked now.
730
        */
731
        dest.x = x;
732
        dest.y = y;
733
        dest.w = image->w;
734
        dest.h = image->h;
735
        SDL_BlitSurface(image, NULL, screen, &dest);
736

    
737
        /* Update the screen area just changed */
738
        SDL_UpdateRects(screen, 1, &dest);
739
}
740

    
741
int alphasortNew(const struct dirent **a, const struct dirent **b) {
742
        int idx1 = atoi((*a)->d_name+5);
743
        int idx2 = atoi((*b)->d_name+5);
744
        return (idx2<idx1);
745
//        return (strcmp((*a)->d_name,(*b)->d_name));
746
}
747

    
748
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
749
        FILE *pFile;
750
        char szFilename[32];
751
        int  y;
752
  
753
  // Open file
754
        sprintf(szFilename, "frame%d.ppm", iFrame);
755
  pFile=fopen(szFilename, "wb");
756
  if(pFile==NULL)
757
    return;
758
  
759
  // Write header
760
  fprintf(pFile, "P5\n%d %d\n255\n", width, height);
761
  
762
  // Write pixel data
763
  for(y=0; y<height; y++)
764
    fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
765
  
766
  // Close file
767
  fclose(pFile);
768
}
769

    
770
static void sigint_handler (int signal) {
771
   printf("Caught SIGINT, exiting...");
772
   got_sigint = 1;
773
}
774

    
775
void ProcessKeys()
776
{
777
        static Uint32 LastTime=0;
778
        static int LastKey=-1;
779

    
780
        Uint32 Now=SDL_GetTicks();
781
        Uint8* keystate=SDL_GetKeyState(NULL);
782
        if(keystate[SDLK_SPACE] &&
783
          (LastKey!=SDLK_SPACE || (LastKey==SDLK_SPACE && (Now-LastTime>1000))))
784
        {
785
                LastKey=SDLK_SPACE;
786
                LastTime=Now;
787
                QueueStopped=!QueueStopped;
788
        }
789
        if(keystate[SDLK_ESCAPE] &&
790
          (LastKey!=SDLK_ESCAPE || (LastKey==SDLK_ESCAPE && (Now-LastTime>1000))))
791
        {
792
                LastKey=SDLK_ESCAPE;
793
                LastTime=Now;
794
                quit=1;
795
        }
796
        /*if(keystate[SDLK_f] &&
797
          (LastKey!=SDLK_f || (LastKey==SDLK_f && (Now-LastTime>1000))))
798
        {
799
                LastKey=SDLK_f;
800
                LastTime=Now;
801
                SDL_WM_ToggleFullScreen(NULL);
802
        }*/
803
}
804

    
805
int main(int argc, char *argv[]) {
806
        int i, j, videoStream,outbuf_size,out_size,out_size_audio,seq_current_chunk = 0,audioStream;
807
        int len1, data_size, stime,cont=0;
808
        int frameFinished, len_audio;
809
        int numBytes,outbuf_audio_size,audio_size;
810

    
811
        int y;
812
        
813
        uint8_t *outbuf,*outbuf_audio;
814
        uint8_t *outbuf_audi_audio;
815
        
816
        AVFormatContext *pFormatCtx;
817

    
818
        AVCodec         *pCodec,*aCodec;
819
        AVFrame         *pFrame; 
820

    
821
        AVPicture pict;
822
        static struct SwsContext *img_convert_ctx;
823
        SDL_Thread *video_thread;//exit_thread,*exit_thread2;
824
        SDL_Event event;
825
        //SDL_mutex   *lock;
826
        SDL_AudioSpec wanted_spec, spec;
827
        
828
        struct MHD_Daemon *daemon = NULL;        
829

    
830
        char buf[1024],outfile[1024], basereadfile[1024],readfile[1024];
831
        FILE *fp;        
832
//        struct dirent **namelist;
833
        int width,height,asample_rate,achannels;
834
        //double framerate;
835

    
836
//  TwBar *bar;
837

    
838
        ThreadVal *tval;
839
        tval = (ThreadVal *)malloc(sizeof(ThreadVal));
840
                
841
        if(argc<5) {
842
                printf("player width height sample_rate channels\n");
843
                exit(1);
844
        }
845
        sscanf(argv[1],"%d",&width);
846
        sscanf(argv[2],"%d",&height);
847
        sscanf(argv[3],"%d",&asample_rate);
848
        sscanf(argv[4],"%d",&achannels);
849
        tval->width = width;
850
        tval->height = height;
851
        //tval->framerate = framerate;
852

    
853

    
854

    
855

    
856
        
857
        // Register all formats and codecs
858

    
859
        av_register_all();
860
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
861
                fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
862
                return -1;
863
        }
864

    
865
        aCodecCtx = avcodec_alloc_context();
866
        //aCodecCtx->bit_rate = 64000;
867
        aCodecCtx->sample_rate = asample_rate;
868
        aCodecCtx->channels = achannels;
869
#ifdef MP3_AUDIO_ENCODER
870
        aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
871
#else
872
        aCodec = avcodec_find_decoder(CODEC_ID_MP2);
873
#endif
874
        printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
875
        if(!aCodec) {
876
                printf("Codec not found!\n");
877
                return -1;
878
        }
879
        if(avcodec_open(aCodecCtx, aCodec)<0) {
880
                fprintf(stderr, "could not open codec\n");
881
                return -1; // Could not open codec
882
        }
883
        printf("using audio Codecid: %d ",aCodecCtx->codec_id);
884
        printf("samplerate: %d ",aCodecCtx->sample_rate);
885
        printf("channels: %d\n",aCodecCtx->channels);
886
        wanted_spec.freq = aCodecCtx->sample_rate;
887
        wanted_spec.format = AUDIO_S16SYS;
888
        wanted_spec.channels = aCodecCtx->channels;
889
        wanted_spec.silence = 0;
890
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
891
        wanted_spec.callback = audio_callback;
892
        wanted_spec.userdata = aCodecCtx;
893
        printf("wantedsizeSDL:%d\n",wanted_spec.size);
894
        if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
895
                fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
896
                return -1;
897
        }
898
        dimAudioQ = spec.size;
899
        deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
900

    
901
        printf("wantedsizeSDL:%d %d\n",wanted_spec.size,wanted_spec.samples);
902

    
903
        printf("freq:%d\n",spec.freq);
904
        printf("format:%d\n",spec.format);
905
        printf("channels:%d\n",spec.channels);
906
        printf("silence:%d\n",spec.silence);
907
        printf("samples:%d\n",spec.samples);
908
        printf("size:%d\n",spec.size);
909

    
910
        pFrame=avcodec_alloc_frame();
911
        if(pFrame==NULL) {
912
                printf("Memory error!!!\n");
913
                return -1;
914
        }
915
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
916

    
917
        strcpy(basereadfile,"chunks/");
918

    
919
        packet_queue_init(&audioq,AUDIO);
920
        packet_queue_init(&videoq,VIDEO);
921
        SDL_WM_SetCaption("Filling buffer...", NULL);
922
        // Make a screen to put our video
923
#ifndef __DARWIN__
924
        screen = SDL_SetVideoMode(width, height, 0, 0);
925
#else
926
        screen = SDL_SetVideoMode(width, height, 24, 0);
927
#endif
928
        if(!screen) {
929
                fprintf(stderr, "SDL: could not set video mode - exiting\n");
930
                exit(1);
931
        }
932

    
933
/*
934
  // Initialize AntTweakBar
935
  TwInit(TW_OPENGL, NULL);
936
  // Tell the window size to AntTweakBar
937
  TwWindowSize(width, height);
938
  // Create a tweak bar
939
  bar = TwNewBar("TweakBar");
940
  // Add 'width' and 'height' to 'bar': they are read-only (RO) variables of type TW_TYPE_INT32.
941
  TwAddVarRO(bar, "Width", TW_TYPE_INT32, &width, " label='Wnd width' help='Width of the graphics window (in pixels)' ");
942
*/
943

    
944
        yuv_overlay = SDL_CreateYUVOverlay(width, height,SDL_YV12_OVERLAY, screen);
945

    
946
        if ( yuv_overlay == NULL ) {
947
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
948
                exit(1);
949
        }
950

    
951
        if ( yuv_overlay->hw_overlay )
952
                fprintf(stderr,"SDL: Using hardware overlay.");
953

    
954
        rect.x = 0;
955
        rect.y = 0;
956
        rect.w = width;
957
        rect.h = height;
958

    
959
        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
960

    
961
        //signal (SIGINT, sigint_handler);
962

    
963
        // Init audio and video buffers
964
        av_init_packet(&AudioPkt);
965
        av_init_packet(&VideoPkt);
966
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
967
        if(!AudioPkt.data) return 0;
968
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
969
        if(!VideoPkt.data) return 0;
970
        
971

    
972
        SDL_PauseAudio(0);
973
        video_thread = SDL_CreateThread(video_callback,tval);
974

    
975

    
976
        //lock = SDL_CreateMutex();
977
        //SDL_WaitThread(exit_thread2,NULL);
978

    
979

    
980

    
981
        daemon = initChunkPuller();
982

    
983

    
984

    
985
        // Wait for user input
986
        while(!quit)
987
        {
988
                if(QueueFillingMode)
989
                        SDL_WM_SetCaption("Filling buffer...", NULL);
990
                else
991
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
992
                SDL_PollEvent(&event);
993
                switch(event.type) {
994
                case SDL_QUIT:
995
                        //exit(0);
996
                        quit=1;
997
                        break;
998
                }
999
                ProcessKeys();
1000
                usleep(20000);
1001
        }
1002
        // Stop audio&video playback
1003

    
1004
printf("1\n");        
1005
        SDL_WaitThread(video_thread,NULL);
1006
printf("2\n");        
1007
        SDL_PauseAudio(1);
1008
printf("3\n");        
1009
        SDL_CloseAudio();
1010
printf("4\n");        
1011
        SDL_Quit();
1012

    
1013
        //SDL_DestroyMutex(lock);
1014
printf("5\n");        
1015
        av_free(aCodecCtx);
1016
printf("6\n");        
1017
        free(AudioPkt.data);
1018
printf("7\n");        
1019
        free(VideoPkt.data);
1020
//        free(namelist);
1021
printf("8\n");        
1022
  free(outbuf_audio);
1023

    
1024
printf("9\n");        
1025
        finalizeChunkPuller(daemon);
1026
printf("10\n");        
1027

    
1028
        return 0;
1029
}
1030

    
1031

    
1032

    
1033
int enqueueBlock(const uint8_t *block, const int block_size) {
1034
        Chunk *gchunk=NULL;
1035
  ExternalChunk *echunk=NULL;
1036
        uint8_t *tempdata, *buffer;
1037
  int i, j;
1038
        Frame *frame=NULL;
1039
        AVPacket packet, packetaudio;
1040

    
1041
        uint8_t *video_bufQ = NULL;
1042
        uint16_t *audio_bufQ = NULL;
1043
        //uint8_t audio_bufQ[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
1044
        int16_t *dataQ;
1045
        int data_sizeQ;
1046
        int lenQ;
1047
        int sizeFrame = 0;
1048
        sizeFrame = 3*sizeof(int)+sizeof(struct timeval);
1049

    
1050
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1051
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1052
        if(!gchunk) {
1053
                printf("Memory error in gchunk!\n");
1054
                return PLAYER_FAIL_RETURN;
1055
        }
1056

    
1057
  decodeChunk(gchunk, block, block_size);
1058

    
1059
        echunk = grapesChunkToExternalChunk(gchunk);
1060
  if(echunk == NULL) {
1061
                printf("Memory error in echunk!\n");
1062
    free(gchunk->attributes);
1063
    free(gchunk->data);
1064
    free(gchunk);
1065
                return PLAYER_FAIL_RETURN;
1066
  }
1067
  free(gchunk->attributes);
1068
  free(gchunk);
1069

    
1070
        frame = (Frame *)malloc(sizeof(Frame));
1071
        if(!frame) {
1072
                printf("Memory error!\n");
1073
                return -1;
1074
        }
1075

    
1076
                tempdata = echunk->data;
1077
                j=echunk->payload_len;
1078
                while(j>0 && !quit) {
1079
                        //usleep(30000);
1080
                        frame->number = *((int *)tempdata);
1081
                        tempdata+=sizeof(int);
1082
                        frame->timestamp = *((struct timeval *)tempdata);
1083
                        tempdata += sizeof(struct timeval);
1084
                        frame->size = *((int *)tempdata);
1085
                        tempdata+=sizeof(int);
1086
                        frame->type = *((int *)tempdata);
1087
                        tempdata+=sizeof(int);
1088

    
1089
                        buffer = tempdata; // here coded frame information
1090
                        tempdata+=frame->size;
1091
                        //printf("%d %d %d %d\n",frame->number,frame->timestamp.tv_usec,frame->size,frame->type);
1092

    
1093
                        if(frame->type!=5) { // video frame
1094
                                av_init_packet(&packet);
1095
                                video_bufQ = (uint8_t *)malloc(frame->size); //this gets freed at the time of packet_queue_get
1096
                                if(video_bufQ) {
1097
                                        memcpy(video_bufQ, buffer, frame->size);
1098
                                        packet.data = video_bufQ;
1099
                                        packet.size = frame->size;
1100
                                        packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1101
                                        packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1102
                                        packet.stream_index = frame->number; // use of stream_index for number frame
1103
                                        //packet.duration = frame->timestamp.tv_sec;
1104
                                        packet_queue_put(&videoq,&packet);
1105
#ifdef DEBUG_SOURCE
1106
                                        printf("SOURCE: Insert video in queue pts=%lld %d %d sindex:%d\n",packet.pts,(int)frame->timestamp.tv_sec,(int)frame->timestamp.tv_usec,packet.stream_index);
1107
#endif
1108
                                }
1109
                        }
1110
                        else { // audio frame
1111
                                av_init_packet(&packetaudio);
1112
                                packetaudio.data = buffer;
1113
                                packetaudio.size = frame->size;
1114

    
1115
                                packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1116
                                packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1117
                                //packetaudio.duration = frame->timestamp.tv_sec;
1118
                                packetaudio.stream_index = 1;
1119
                                packetaudio.flags = 1;
1120
                                packetaudio.pos = -1;
1121
                                packetaudio.convergence_duration = -1;
1122

    
1123
                                // insert the audio frame into the queue
1124
                                data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1125
        lenQ = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_bufQ, &data_sizeQ, &packetaudio);
1126
                                if(lenQ>0)
1127
                                {
1128
                                        // for freeing there is some memory still in tempdata to be freed
1129
                                        dataQ = (int16_t *)malloc(data_sizeQ); //this gets freed at the time of packet_queue_get
1130
                                        if(dataQ)
1131
                                        {
1132
                                                memcpy(dataQ,audio_bufQ,data_sizeQ);
1133
                                                packetaudio.data = (int8_t *)dataQ;
1134
                                                packetaudio.size = data_sizeQ;
1135
                                                packetaudio.stream_index = frame->number; // use of stream_index for number frame
1136
                
1137
                                                packet_queue_put(&audioq,&packetaudio);
1138
#ifdef DEBUG_SOURCE
1139
                                                printf("SOURCE: Insert audio in queue pts=%lld\n",packetaudio.pts);
1140
#endif
1141
                                        }
1142
                                }
1143

    
1144
                        }
1145
                        j = j - sizeFrame - frame->size;
1146
                }
1147

    
1148
        
1149
/*
1150
                if(QueueFillingMode)
1151
                        SDL_WM_SetCaption("Filling buffer...", NULL);
1152
                else
1153
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
1154
                SDL_PollEvent(&event);
1155
                switch(event.type) {
1156
                case SDL_QUIT:
1157
                        //exit(0);
1158
                        quit=1;
1159
                        break;
1160
                }
1161
                ProcessKeys();
1162
*/
1163
  free(echunk->data);
1164
        free(echunk);
1165
        free(frame);
1166
  av_free(audio_bufQ);
1167
}