Statistics
| Branch: | Revision:

chunker-player / chunker_player.c @ 1e69ae95

History | View | Annotate | Download (24.6 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 "chunker_player.h"
32

    
33
#define SDL_AUDIO_BUFFER_SIZE 1024
34

    
35
#define QUEUE_FILLING_THRESHOLD        50
36
#define AUDIO        1
37
#define VIDEO        2
38

    
39
//#define DEBUG_AUDIO
40
//#define DEBUG_VIDEO
41
//#define DEBUG_QUEUE
42
//#define DEBUG_SOURCE
43

    
44
short int QueueFillingMode=1;
45
short int QueueStopped=0;
46

    
47
typedef struct PacketQueue {
48
        AVPacketList *first_pkt, *last_pkt;
49
        int nb_packets;
50
        int size;
51
        SDL_mutex *mutex;
52
        SDL_cond *cond;
53
        short int queueType;
54
} PacketQueue;
55

    
56
typedef struct threadVal {
57
        int width;
58
        int height;
59
} ThreadVal;
60

    
61
int AudioQueueOffset=0;
62
PacketQueue audioq;
63
PacketQueue videoq;
64
AVPacket AudioPkt, VideoPkt;
65
int quit = 0;
66

    
67
SDL_Surface *screen;
68
SDL_Overlay *yuv_overlay;
69
SDL_Rect    rect;
70

    
71
int got_sigint = 0;
72

    
73
#define MAX_TOLLERANCE 60
74

    
75
long long DeltaTimeAudio, DeltaTimeVideo;
76
short int FirstTimeAudio=1, FirstTimeVideo = 1;
77

    
78
int dimAudioQ;
79
float deltaAudioQ;
80

    
81
void packet_queue_init(PacketQueue *q, short int Type) {
82
        memset(q,0,sizeof(PacketQueue));
83
        q->mutex = SDL_CreateMutex();
84
        q->cond = SDL_CreateCond();
85
        QueueFillingMode=1;
86
        q->queueType=Type;
87
}
88

    
89
int packet_queue_put(PacketQueue *q, AVPacket *pkt) {
90
        AVPacketList *pkt1;
91
        if(av_dup_packet(pkt) < 0) {
92
                return -1;
93
        }
94
        pkt1 = av_malloc(sizeof(AVPacketList));
95
        if (!pkt1)
96
                return -1;
97
        pkt1->pkt = *pkt;
98
        pkt1->next = NULL;
99

    
100
        SDL_LockMutex(q->mutex);
101

    
102
        if (!q->last_pkt)
103
                q->first_pkt = pkt1;
104
        else
105
                q->last_pkt->next = pkt1;
106
        q->last_pkt = pkt1;
107
        q->nb_packets++;
108
        q->size += pkt1->pkt.size;
109
#ifdef DEBUG_QUEUE
110
        printf("PUT in Queue: NPackets=%d Type=%d\n",q->nb_packets,q->queueType);
111
#endif
112

    
113
        if(q->nb_packets>=QUEUE_FILLING_THRESHOLD && QueueFillingMode) // && q->queueType==AUDIO)
114
        {
115
                QueueFillingMode=0;
116
                //SDL_CondSignal(q->cond);
117
        }
118

    
119
        SDL_UnlockMutex(q->mutex);
120
        return 0;
121
}
122

    
123
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, short int av) {
124
        //AVPacket tmp;
125
        AVPacketList *pkt1;
126
        int ret=-1;
127
        int SizeToCopy=0;
128

    
129
#ifdef DEBUG_QUEUE
130
        printf("QUEUE Get NPackets=%d Type=%d\n",q->nb_packets,q->queueType);
131
#endif
132

    
133
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
134
        {
135
                return -1;
136
                //SDL_CondWait(q->cond, q->mutex);
137
        }
138

    
139
        SDL_LockMutex(q->mutex);
140
        pkt1 = q->first_pkt;
141
        if (pkt1) {
142
                if(av==1) {
143
                        if(pkt1->pkt.size-AudioQueueOffset>dimAudioQ) {
144
#ifdef DEBUG_QUEUE
145
                                printf("Extract from the same packet ");
146
#endif
147
                                //av_init_packet(&tmp);
148
                                q->size -= dimAudioQ;
149
                                pkt->size = dimAudioQ;
150
                                //tmp.data = pkt1->pkt.data+AudioQueueOffset;
151
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
152
                                pkt->dts = pkt1->pkt.dts;
153
                                pkt->pts = pkt1->pkt.pts;
154
                                pkt->stream_index = 1;
155
                                pkt->flags = 1;
156
                                pkt->pos = -1;
157
                                pkt->convergence_duration = -1;
158

    
159
                                //*pkt = tmp;
160
                                //pkt1->pkt.size -= dimAudioQ;
161
                                pkt1->pkt.dts += deltaAudioQ;
162
                                pkt1->pkt.pts += deltaAudioQ;
163
                                AudioQueueOffset += dimAudioQ;
164
#ifdef DEBUG_QUEUE
165
                                printf("AudioQueueOffset = %d\n",AudioQueueOffset);
166
#endif
167
                                
168
                                ret = 1;
169
                        }
170
                        else {
171
#ifdef DEBUG_QUEUE
172
                                printf("Extract from 2 packets ");
173
#endif
174
                                // Check for loss
175
                                if(pkt1->next)
176
                                {
177
                                        //av_init_packet(&tmp);
178
                                        pkt->size = dimAudioQ;
179
                                        pkt->dts = pkt1->pkt.dts;
180
                                        pkt->pts = pkt1->pkt.pts;
181
                                        pkt->stream_index = 1;
182
                                        pkt->flags = 1;
183
                                        pkt->pos = -1;
184
                                        pkt->convergence_duration = -1;
185
                                        //tmp.data = (uint8_t *)malloc(sizeof(uint8_t)*dimAudioQ);
186
                                        //if(tmp.data)
187
                                        {
188
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
189
#ifdef DEBUG_QUEUE
190
                                                printf("SizeToCopy=%d ",SizeToCopy);
191
#endif
192
                                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,SizeToCopy);
193
                                                memcpy(pkt->data+SizeToCopy,pkt1->next->pkt.data,(dimAudioQ-SizeToCopy)*sizeof(uint8_t));
194
                                        }
195
                                        //*pkt = tmp;
196
                                }
197
                                q->first_pkt = pkt1->next;
198
                                if (!q->first_pkt)
199
                                        q->last_pkt = NULL;
200
                                q->nb_packets--;
201
                                q->size -= SizeToCopy;
202
                                free(pkt1->pkt.data);
203
                                av_free(pkt1);
204
                                // Adjust timestamps
205
                                pkt1 = q->first_pkt;
206
                                if(pkt1)
207
                                {
208
                                        pkt1->pkt.dts = pkt->dts + deltaAudioQ;
209
                                        pkt1->pkt.pts = pkt->pts + deltaAudioQ;
210
                                        AudioQueueOffset=dimAudioQ-SizeToCopy;
211
                                        q->size -= AudioQueueOffset;
212
                                        ret = 1;
213
                                }
214
                                else
215
                                {
216
                                        AudioQueueOffset=0;
217
                                }
218
#ifdef DEBUG_QUEUE
219
                                printf("AudioQueueOffset = %d\n",AudioQueueOffset);
220
#endif
221
                        }
222
                }
223
                else {
224
                        q->first_pkt = pkt1->next;
225
                        if (!q->first_pkt)
226
                                q->last_pkt = NULL;
227
                        q->nb_packets--;
228
                        q->size -= pkt1->pkt.size;
229
                        
230
                        pkt->size = pkt1->pkt.size;
231
                        pkt->dts = pkt1->pkt.dts;
232
                        pkt->pts = pkt1->pkt.pts;
233
                        pkt->stream_index = pkt1->pkt.stream_index;
234
                        pkt->flags = pkt1->pkt.flags;
235
                        pkt->pos = pkt1->pkt.pos;
236
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
237
                        //*pkt = pkt1->pkt;
238
                        memcpy(pkt->data,pkt1->pkt.data,pkt1->pkt.size);
239
                        free(pkt1->pkt.data);
240
                        av_free(pkt1);
241
                        ret = 1;
242
                }
243
        }
244
        if(q->nb_packets==0 && q->queueType==AUDIO)
245
                QueueFillingMode=1;
246

    
247
        SDL_UnlockMutex(q->mutex);
248
        return ret;
249
}
250

    
251

    
252
int audio_decode_frame(uint8_t *audio_buf, int buf_size) {
253
        //struct timeval now;
254
        int audio_pkt_size = 0;
255
        long long Now;
256
        short int DecodeAudio=0, SkipAudio=0;
257
        //int len1, data_size;
258

    
259
        //gettimeofday(&now,NULL);
260
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
261
        Now=(long long)SDL_GetTicks();
262

    
263
        if(QueueFillingMode || QueueStopped)
264
        {
265
                FirstTimeAudio=1;
266
                return -1;
267
        }
268

    
269
        if(FirstTimeAudio==1 && audioq.size>0) {
270
                if(audioq.first_pkt->pkt.pts>0)
271
                {
272
                        DeltaTimeAudio=Now-(long long)(audioq.first_pkt->pkt.pts);
273
                        FirstTimeAudio = 0;
274
#ifdef DEBUG_AUDIO 
275
                         printf("audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTimeAudio);
276
#endif
277
                }
278
        }
279

    
280
#ifdef DEBUG_AUDIO 
281
        if(audioq.first_pkt)
282
        {
283
                printf("audio_decode_frame - Syncro params: DeltaNow-pts=%lld ",(Now-((long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio)));
284
                printf("pts=%lld ",(long long)audioq.first_pkt->pkt.pts);
285
                printf("Tollerance=%d ",(int)MAX_TOLLERANCE);
286
                printf("QueueLen=%d ",(int)audioq.nb_packets);
287
                printf("QueueSize=%d\n",(int)audioq.size);
288
        }
289
        else
290
                printf("audio_decode_frame - Empty queue\n");
291
#endif
292

    
293

    
294
        if(audioq.nb_packets>0) {
295
                if((long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio<Now-(long long)MAX_TOLLERANCE) {
296
                        SkipAudio = 1;
297
                        DecodeAudio = 0;
298
                }
299
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio>=Now-(long long)MAX_TOLLERANCE &&
300
                        (long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio<=Now+(long long)MAX_TOLLERANCE) {
301
                                SkipAudio = 0;
302
                                DecodeAudio = 1;
303
                }
304
        }
305
                
306
        while(SkipAudio==1 && audioq.size>0) {
307
                SkipAudio = 0;
308
#ifdef DEBUG_AUDIO
309
                 printf("skipaudio: queue size=%d\n",audioq.size);
310
#endif
311
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
312
                        return -1;
313
                }
314
                if(audioq.first_pkt)
315
                {
316
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio<Now-(long long)MAX_TOLLERANCE) {
317
                                SkipAudio = 1;
318
                                DecodeAudio = 0;
319
                        }
320
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio>=Now-(long long)MAX_TOLLERANCE &&
321
                                (long long)audioq.first_pkt->pkt.pts+DeltaTimeAudio<=Now+(long long)MAX_TOLLERANCE) {
322
                                        SkipAudio = 0;
323
                                        DecodeAudio = 1;
324
                        }
325
                }
326
        }
327
        if(DecodeAudio==1) {
328
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
329
                        return -1;
330
                }
331
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
332
                audio_pkt_size = AudioPkt.size;
333
#ifdef DEBUG_AUDIO
334
                 printf("Decode audio\n");
335
#endif
336
        }
337

    
338
        return audio_pkt_size;
339

    
340
}
341

    
342
/*static long get_time_diff(struct timeval time_now) {
343
        struct timeval time_now2;
344
        gettimeofday(&time_now2,0);
345
        return time_now2.tv_sec*1.e6 - time_now.tv_sec*1.e6 + time_now2.tv_usec - time_now.tv_usec;
346
}*/
347

    
348
int video_callback(void *valthread) {
349
        //AVPacket pktvideo;
350
        AVCodecContext  *pCodecCtx;
351
        AVCodec         *pCodec;
352
        AVFrame                *pFrame;
353
        AVPacket        packet;
354
        int                frameFinished;
355
        int                 countexit;
356
        AVPicture pict;
357
        static struct SwsContext *img_convert_ctx;
358
        //FILE *frecon;
359
        SDL_Event event;
360
        long long Now;
361
        short int SkipVideo, DecodeVideo;
362

    
363
        //double frame_rate = 0.0,time_between_frames=0.0;
364
        //struct timeval now;
365

    
366
        //int wait_for_sync = 1;
367
        ThreadVal *tval;
368
        tval = (ThreadVal *)valthread;
369

    
370
        //frame_rate = tval->framerate;
371
        //time_between_frames = 1.e6 / frame_rate;
372
        //gettimeofday(&time_now,0);
373

    
374
        //frecon = fopen("recondechunk.mpg","wb");
375

    
376
        pCodecCtx=avcodec_alloc_context();
377
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
378
        pCodecCtx->codec_id   = 13;//CODEC_ID_H264;
379
        //pCodecCtx->me_range = 16;
380
        //pCodecCtx->max_qdiff = 4;
381
        //pCodecCtx->qmin = 10;
382
        //pCodecCtx->qmax = 51;
383
        //pCodecCtx->qcompress = 0.6;
384
        pCodecCtx->bit_rate = 400000;
385
        // resolution must be a multiple of two
386
        pCodecCtx->width = tval->width;//176;//352;
387
        pCodecCtx->height = tval->height;//144;//288;
388
        // frames per second
389
        pCodecCtx->time_base= (AVRational){1,25};
390
        pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
391
        pCodecCtx->max_b_frames=1;
392
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
393
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
394

    
395
        if(pCodec==NULL) {
396
                fprintf(stderr, "Unsupported codec!\n");
397
                return -1; // Codec not found
398
        }
399
        if(avcodec_open(pCodecCtx, pCodec)<0) {
400
                fprintf(stderr, "could not open codec\n");
401
                return -1; // Could not open codec
402
        }
403
        pFrame=avcodec_alloc_frame();
404
        if(pFrame==NULL) {
405
                printf("Memory error!!!\n");
406
                return -1;
407
        }
408

    
409
        while(!quit) {
410
                if(QueueFillingMode || QueueStopped)
411
                {
412
                        FirstTimeVideo=1;
413
                        usleep(5000);
414
                        continue;
415
                }
416

    
417
                DecodeVideo = 0;
418
                SkipVideo = 0;
419
                //gettimeofday(&now,NULL);
420
                //Now = (unsigned long long)now.tv_sec*1000+(unsigned long long)now.tv_usec/1000;
421
                Now=(long long)SDL_GetTicks();
422
                if(FirstTimeVideo==1 && videoq.size>0) {
423
                        if(videoq.first_pkt->pkt.pts>0)
424
                        {
425
                                DeltaTimeVideo=Now-(long long)videoq.first_pkt->pkt.pts;
426
                                FirstTimeVideo = 0;
427
                        }
428
#ifdef DEBUG_VIDEO 
429
                         printf("VideoCallback - DeltaTimeAudio=%lld\n",DeltaTimeVideo);
430
#endif
431
                }
432

    
433
#ifdef DEBUG_VIDEO 
434
                if(videoq.first_pkt)
435
                {
436
                        printf("VideoCallback - Syncro params: Delta:%lld Now:%lld pts=%lld ",(long long)DeltaTimeVideo,Now,(long long)videoq.first_pkt->pkt.pts);
437
                        printf("pts=%lld ",(long long)videoq.first_pkt->pkt.pts);
438
                        printf("Tollerance=%d ",(int)MAX_TOLLERANCE);
439
                        printf("QueueLen=%d ",(int)videoq.nb_packets);
440
                        printf("QueueSize=%d\n",(int)videoq.size);
441
                }
442
                else
443
                        printf("VideoCallback - Empty queue\n");
444
#endif
445

    
446
                if(videoq.nb_packets>0) {
447
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo)<Now-(long long)MAX_TOLLERANCE) {
448
                                SkipVideo = 1;
449
                                DecodeVideo = 0;
450
                        }
451
                        else 
452
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo)>=Now-(long long)MAX_TOLLERANCE &&
453
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo)<=Now+(long long)MAX_TOLLERANCE) {
454
                                        SkipVideo = 0;
455
                                        DecodeVideo = 1;
456
                                }
457
                }
458
                printf("skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
459

    
460
                while(SkipVideo==1 && videoq.size>0) {
461
                        SkipVideo = 0;
462
#ifdef DEBUG_VIDEO 
463
                         printf("Skip Video\n");
464
#endif
465
                        if(packet_queue_get(&videoq,&VideoPkt,0) < 0) {
466
                                break;
467
                        }
468
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
469
                        if(videoq.first_pkt)
470
                        {
471
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo<Now-(long long)MAX_TOLLERANCE) {
472
                                        SkipVideo = 1;
473
                                        DecodeVideo = 0;
474
                                }
475
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo>=Now-(long long)MAX_TOLLERANCE &&
476
                                        (long long)videoq.first_pkt->pkt.pts+DeltaTimeVideo<=Now+(long long)MAX_TOLLERANCE) {
477
                                        SkipVideo = 0;
478
                                        DecodeVideo = 1;
479
                                }
480
                        }
481
                }
482
                
483
                if(DecodeVideo==1) {
484
                        if(packet_queue_get(&videoq,&VideoPkt,0) > 0) {
485

    
486
#ifdef DEBUG_VIDEO
487
                                printf("Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTimeVideo,Now);
488
#endif
489

    
490
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
491

    
492
                                       if(frameFinished) { // it must be true all the time else error
493
        //                                 printf("FrameFinished\n");
494
                                        //SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height, cont++);
495
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
496

    
497
                                        // Lock SDL_yuv_overlay
498
                                        if ( SDL_MUSTLOCK(screen) ) {
499
                                                if ( SDL_LockSurface(screen) < 0 ) break;
500
                                        }
501
                                        if (SDL_LockYUVOverlay(yuv_overlay) < 0) break;
502

    
503
                                        pict.data[0] = yuv_overlay->pixels[0];
504
                                        pict.data[1] = yuv_overlay->pixels[2];
505
                                        pict.data[2] = yuv_overlay->pixels[1];
506

    
507
                                        pict.linesize[0] = yuv_overlay->pitches[0];
508
                                        pict.linesize[1] = yuv_overlay->pitches[2];
509
                                        pict.linesize[2] = yuv_overlay->pitches[1];
510
                                        img_convert_ctx = sws_getContext(tval->width,tval->height,PIX_FMT_YUV420P,tval->width,tval->height,PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);
511

    
512
                                        if(img_convert_ctx==NULL) {
513
                                                fprintf(stderr,"Cannot initialize the conversion context!\n");
514
                                                exit(1);
515
                                        }
516
                                        sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,0,tval->height,pict.data,pict.linesize);
517

    
518
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
519
                                        if ( SDL_MUSTLOCK(screen) ) {
520
                                                SDL_UnlockSurface(screen);
521
                                        }
522
                                        SDL_UnlockYUVOverlay(yuv_overlay);
523

    
524
                                        // Show, baby, show!
525
                                        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
526
                        
527
                                }
528
                        }
529
                }
530

    
531
                usleep(5000);
532

    
533
                /*SDL_PollEvent(&event);
534
                switch(event.type) {
535
                case SDL_QUIT:
536
                        quit=1;
537
                        //exit(0);
538
                        break;
539
                }*/
540
        }
541
        av_free(pCodecCtx);
542
        //fclose(frecon);
543
#ifdef DEBUG_VIDEO
544
         printf("video callback end\n");
545
#endif
546
        return 1;
547
}
548

    
549
/*int audio_decode_frame2(uint8_t *audio_buf,int len) {
550
        AVPacket pkt;
551
        if(packet_queue_get(&audioq, &pkt, 1,1) < 0) {
552
                return -1;
553
        }
554
        memcpy(audio_buf,pkt.data,pkt.size);
555
        //printf("tornato : %d bytes\n",pkt.size);
556
        return pkt.size;
557
}*/
558

    
559
void audio_callback(void *userdata, Uint8 *stream, int len) {
560

    
561
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
562
        int audio_size;
563

    
564
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
565

    
566
        audio_size = audio_decode_frame(audio_buf, sizeof(audio_buf));
567
        if(audio_size != len) {
568
                memset(stream, 0, len);
569
        } else {
570
                memcpy(stream, (uint8_t *)audio_buf, len);
571
        }
572
}
573

    
574
void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
575
        SDL_Surface *image;
576
        SDL_Rect dest;
577

    
578
        /* Load a BMP file on a surface */
579
        image = SDL_LoadBMP(file);
580
        if ( image == NULL ) {
581
                fprintf(stderr, "Error loading %s: %s\n", file, SDL_GetError());
582
                return;
583
        }
584

    
585
        /* Copy on the screen surface 
586
        surface should be blocked now.
587
        */
588
        dest.x = x;
589
        dest.y = y;
590
        dest.w = image->w;
591
        dest.h = image->h;
592
        SDL_BlitSurface(image, NULL, screen, &dest);
593

    
594
        /* Update the screen area just changed */
595
        SDL_UpdateRects(screen, 1, &dest);
596
}
597

    
598
int alphasortNew(const struct dirent **a, const struct dirent **b) {
599
        int idx1 = atoi((*a)->d_name+5);
600
        int idx2 = atoi((*b)->d_name+5);
601
        return (idx2<idx1);
602
//        return (strcmp((*a)->d_name,(*b)->d_name));
603
}
604

    
605
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
606
        FILE *pFile;
607
        char szFilename[32];
608
        int  y;
609
  
610
  // Open file
611
        sprintf(szFilename, "frame%d.ppm", iFrame);
612
  pFile=fopen(szFilename, "wb");
613
  if(pFile==NULL)
614
    return;
615
  
616
  // Write header
617
  fprintf(pFile, "P5\n%d %d\n255\n", width, height);
618
  
619
  // Write pixel data
620
  for(y=0; y<height; y++)
621
    fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
622
  
623
  // Close file
624
  fclose(pFile);
625
}
626

    
627
static void sigint_handler (int signal) {
628
   printf("Caught SIGINT, exiting...");
629
   got_sigint = 1;
630
}
631

    
632
void ProcessKeys()
633
{
634
        static Uint32 LastTime=0;
635
        static int LastKey=-1;
636

    
637
        Uint32 Now=SDL_GetTicks();
638
        Uint8* keystate=SDL_GetKeyState(NULL);
639
        if(keystate[SDLK_SPACE] &&
640
          (LastKey!=SDLK_SPACE || (LastKey==SDLK_SPACE && (Now-LastTime>1000))))
641
        {
642
                LastKey=SDLK_SPACE;
643
                LastTime=Now;
644
                QueueStopped=!QueueStopped;
645
        }
646
        if(keystate[SDLK_ESCAPE] &&
647
          (LastKey!=SDLK_ESCAPE || (LastKey==SDLK_ESCAPE && (Now-LastTime>1000))))
648
        {
649
                LastKey=SDLK_ESCAPE;
650
                LastTime=Now;
651
                quit=1;
652
        }
653
        /*if(keystate[SDLK_f] &&
654
          (LastKey!=SDLK_f || (LastKey==SDLK_f && (Now-LastTime>1000))))
655
        {
656
                LastKey=SDLK_f;
657
                LastTime=Now;
658
                SDL_WM_ToggleFullScreen(NULL);
659
        }*/
660
}
661

    
662
int main(int argc, char *argv[]) {
663
        int videoStream,outbuf_size,out_size,out_size_audio,seq_current_chunk = 0,audioStream;
664
        int len1, data_size, stime,cont=0;
665
        int frameFinished, len_audio;
666
        int numBytes,outbuf_audio_size,audio_size;
667

    
668
        int dir_entries,y;
669
        
670
        uint8_t *outbuf,*outbuf_audio;
671
        uint8_t *outbuf_audi_audio;
672
        
673
        AVFormatContext *pFormatCtx;
674

    
675
        AVCodec         *pCodec,*aCodec;
676
        AVFrame         *pFrame; 
677

    
678
        AVPicture pict;
679
        static struct SwsContext *img_convert_ctx;
680
        SDL_Thread *video_thread;//exit_thread,*exit_thread2;
681
        SDL_Event event;
682
        //SDL_mutex   *lock;
683
        SDL_AudioSpec wanted_spec, spec;
684
        
685
                
686
        char buf[1024],outfile[1024], basereadfile[1024],readfile[1024];
687
        FILE *fp;        
688
        struct dirent **namelist;
689
        int width,height;
690
        //double framerate;
691

    
692

    
693

    
694
        ThreadVal *tval;
695
        tval = (ThreadVal *)malloc(sizeof(ThreadVal));
696
                
697
        if(argc<3) {
698
                printf("player width height\n");
699
                exit(1);
700
        }
701
        sscanf(argv[1],"%d",&width);
702
        sscanf(argv[2],"%d",&height);
703
        tval->width = width;
704
        tval->height = height;
705
        //tval->framerate = framerate;
706

    
707

    
708

    
709

    
710
        
711
        // Register all formats and codecs
712

    
713
        av_register_all();
714
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
715
                fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
716
                return -1;
717
        }
718

    
719
        aCodecCtx = avcodec_alloc_context();
720
        aCodecCtx->bit_rate = 64000;
721
        aCodecCtx->sample_rate = 44100;
722
        aCodecCtx->channels = 2;
723
        aCodec = avcodec_find_decoder(CODEC_ID_MP2); //CODEC_ID_MP3// codec audio
724
        printf("IDMP2%d IDMP3%d\n",CODEC_ID_MP2,CODEC_ID_MP3);
725
        if(!aCodec) {
726
                printf("Codec not found!\n");
727
                return -1;
728
        }
729
        if(avcodec_open(aCodecCtx, aCodec)<0) {
730
                fprintf(stderr, "could not open codec\n");
731
                return -1; // Could not open codec
732
        }
733
        printf("Codecid: %d %d",aCodecCtx->codec_id,aCodecCtx->sample_rate);
734
        printf("samplerate: %d",aCodecCtx->sample_rate);
735
        printf("channels: %d",aCodecCtx->channels);
736
        wanted_spec.freq = aCodecCtx->sample_rate;
737
        wanted_spec.format = AUDIO_S16SYS;
738
        wanted_spec.channels = aCodecCtx->channels;
739
        wanted_spec.silence = 0;
740
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
741
        wanted_spec.callback = audio_callback;
742
        wanted_spec.userdata = aCodecCtx;
743
        printf("wantedsizeSDL:%d\n",wanted_spec.size);
744
        if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
745
                fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
746
                return -1;
747
        }
748
        dimAudioQ = spec.size;
749
        deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
750

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

    
753
        printf("freq:%d\n",spec.freq);
754
        printf("format:%d\n",spec.format);
755
        printf("channels:%d\n",spec.channels);
756
        printf("silence:%d\n",spec.silence);
757
        printf("samples:%d\n",spec.samples);
758
        printf("size:%d\n",spec.size);
759

    
760
        pFrame=avcodec_alloc_frame();
761
        if(pFrame==NULL) {
762
                printf("Memory error!!!\n");
763
                return -1;
764
        }
765
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
766

    
767
        strcpy(basereadfile,"chunks/");
768

    
769
        packet_queue_init(&audioq,AUDIO);
770
        packet_queue_init(&videoq,VIDEO);
771
        SDL_WM_SetCaption("Filling buffer...", NULL);
772
        // Make a screen to put our video
773
#ifndef __DARWIN__
774
        screen = SDL_SetVideoMode(width, height, 0, 0);
775
#else
776
        screen = SDL_SetVideoMode(width, height, 24, 0);
777
#endif
778
        if(!screen) {
779
                fprintf(stderr, "SDL: could not set video mode - exiting\n");
780
                exit(1);
781
        }
782

    
783
        yuv_overlay = SDL_CreateYUVOverlay(width, height,SDL_YV12_OVERLAY, screen);
784

    
785
        if ( yuv_overlay == NULL ) {
786
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
787
                exit(1);
788
        }
789

    
790
        if ( yuv_overlay->hw_overlay )
791
                fprintf(stderr,"SDL: Using hardware overlay.");
792

    
793
        rect.x = 0;
794
        rect.y = 0;
795
        rect.w = width;
796
        rect.h = height;
797

    
798
        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
799

    
800
        //signal (SIGINT, sigint_handler);
801

    
802
        // Init audio and video buffers
803
        av_init_packet(&AudioPkt);
804
        av_init_packet(&VideoPkt);
805
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
806
        if(!AudioPkt.data) return 0;
807
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
808
        if(!VideoPkt.data) return 0;
809
        
810

    
811
        SDL_PauseAudio(0);
812
        video_thread = SDL_CreateThread(video_callback,tval);
813

    
814

    
815
        //lock = SDL_CreateMutex();
816
        //SDL_WaitThread(exit_thread2,NULL);
817

    
818
#ifdef DEBUG_SOURCE
819
        printf("SOURCE: Num entries=%d\n",dir_entries);
820
#endif
821

    
822

    
823
        initChunkPuller();
824

    
825

    
826

    
827
        // Wait for user input
828
        while(!quit)
829
        {
830
                if(QueueFillingMode)
831
                        SDL_WM_SetCaption("Filling buffer...", NULL);
832
                else
833
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
834
                SDL_PollEvent(&event);
835
                switch(event.type) {
836
                case SDL_QUIT:
837
                        //exit(0);
838
                        quit=1;
839
                        break;
840
                }
841
                ProcessKeys();
842
                usleep(20000);
843
        }
844
        // Stop audio&video playback
845
        SDL_WaitThread(video_thread,NULL);
846
        SDL_PauseAudio(1);
847
        SDL_CloseAudio();
848

    
849
        //SDL_DestroyMutex(lock);
850
        av_free(aCodecCtx);
851
        free(AudioPkt.data);
852
        free(VideoPkt.data);
853
        free(namelist);
854

    
855

    
856
        return 0;
857
}
858

    
859

    
860

    
861
int enqueueBlock(const uint8_t *block, const int block_size) {
862
        Chunk *gchunk=NULL;
863
  ExternalChunk *echunk=NULL;
864
        uint8_t *tempdata, *buffer;
865
  int i, j;
866
        Frame *frame=NULL;
867
        AVPacket packet, packetaudio;
868

    
869
        uint8_t audio_bufQ[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
870
        int16_t *dataQ;
871
        int data_sizeQ;
872
        int lenQ;
873
        int sizeFrame = 0;
874
        sizeFrame = 3*sizeof(int)+sizeof(struct timeval);
875

    
876
        gchunk = (Chunk *)malloc(sizeof(Chunk));
877
        if(!gchunk) {
878
                printf("Memory error!\n");
879
                return PLAYER_FAIL_RETURN;
880
        }
881

    
882
  decodeChunk(gchunk, block, block_size);
883

    
884
        echunk = grapesChunkToExternalChunk(gchunk);
885
  free(gchunk);
886

    
887
        frame = (Frame *)malloc(sizeof(Frame));
888
        if(!frame) {
889
                printf("Memory error!\n");
890
                return -1;
891
        }
892

    
893
                tempdata = echunk->data;
894
                j=echunk->payload_len;
895
                while(j>0 && !quit) {
896
                        //usleep(30000);
897
                        frame->number = *((int *)tempdata);
898
                        tempdata+=sizeof(int);
899
                        frame->timestamp = *((struct timeval *)tempdata);
900
                        tempdata += sizeof(struct timeval);
901
                        frame->size = *((int *)tempdata);
902
                        tempdata+=sizeof(int);
903
                        frame->type = *((int *)tempdata);
904
                        tempdata+=sizeof(int);
905

    
906
                        buffer = tempdata; // here coded frame information
907
                        tempdata+=frame->size;
908
                        //printf("%d %d %d %d\n",frame->number,frame->timestamp.tv_usec,frame->size,frame->type);
909

    
910
                        if(frame->type!=5) { // video frame
911
                                av_init_packet(&packet);
912
                                packet.data = buffer;
913
                                packet.size = frame->size;
914
                                packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
915
                                packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
916
                                //packet.duration = frame->timestamp.tv_sec;
917
                                packet_queue_put(&videoq,&packet);
918
#ifdef DEBUG_SOURCE
919
                                printf("SOURCE: Insert video in queue pts=%lld %d %d\n",packet.pts,(int)frame->timestamp.tv_sec,(int)frame->timestamp.tv_usec);
920
#endif
921
                        }
922
                        else { // audio frame
923
                                av_init_packet(&packetaudio);
924
                                packetaudio.data = buffer;
925
                                packetaudio.size = frame->size;
926

    
927
                                packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
928
                                packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
929
                                //packetaudio.duration = frame->timestamp.tv_sec;
930
                                packetaudio.stream_index = 1;
931
                                packetaudio.flags = 1;
932
                                packetaudio.pos = -1;
933
                                packetaudio.convergence_duration = -1;
934

    
935
                                // insert the audio frame into the queue
936
                                data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
937
                                lenQ = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_bufQ, &data_sizeQ, &packetaudio);
938
                                if(lenQ>0)
939
                                {
940
                                        // for freeing there is some memory still in tempdata to be freed
941
                                        dataQ = (int16_t *)malloc(data_sizeQ);
942
                                        if(dataQ)
943
                                        {
944
                                                memcpy(dataQ,audio_bufQ,data_sizeQ);
945
                                                packetaudio.data = (int8_t *)dataQ;
946
                                                packetaudio.size = data_sizeQ;
947
                
948
                                                packet_queue_put(&audioq,&packetaudio);
949
#ifdef DEBUG_SOURCE
950
                                                printf("SOURCE: Insert audio in queue pts=%lld\n",packetaudio.pts);
951
#endif
952
                                        }
953
                                }
954

    
955
                        }
956
                        j = j - sizeFrame - frame->size;
957
                }
958

    
959
        
960
/*
961
                if(QueueFillingMode)
962
                        SDL_WM_SetCaption("Filling buffer...", NULL);
963
                else
964
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
965
                SDL_PollEvent(&event);
966
                switch(event.type) {
967
                case SDL_QUIT:
968
                        //exit(0);
969
                        quit=1;
970
                        break;
971
                }
972
                ProcessKeys();
973
*/
974
        free(echunk);
975
        free(frame);
976
}