Statistics
| Branch: | Revision:

chunker-player / chunker_player.c @ 64144d8f

History | View | Annotate | Download (34.8 KB)

1
// player.c
2
// Author 
3
// Diego Reforgiato, Dario Marchese, Carmelo Daniele, Giuseppe Tropea
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

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

    
32
#include <platform.h>
33
#include <microhttpd.h>
34

    
35
#include <http_default_urls.h>
36
#include "chunker_player.h"
37
#include "codec_definitions.h"
38

    
39
#define SDL_AUDIO_BUFFER_SIZE 1024
40

    
41
#define MAX_TOLLERANCE 40
42
#define AUDIO        1
43
#define VIDEO        2
44

    
45
//#define DEBUG_AUDIO
46
//#define DEBUG_VIDEO
47
//#define DEBUG_QUEUE
48
//#define DEBUG_SOURCE
49
#define DEBUG_STATS
50
//#define DEBUG_AUDIO_BUFFER
51
//#define DEBUG_CHUNKER
52

    
53

    
54
short int QueueFillingMode=1;
55
short int QueueStopped=0;
56

    
57
typedef struct PacketQueue {
58
        AVPacketList *first_pkt;
59
        //AVPacketList *last_pkt;
60
        int nb_packets;
61
        int size;
62
        SDL_mutex *mutex;
63
        short int queueType;
64
        int last_frame_extracted; //HINT THIS SHOULD BE MORE THAN 4 BYTES
65
        int total_lost_frames;
66
} PacketQueue;
67

    
68
typedef struct threadVal {
69
        int width;
70
        int height;
71
        float aspect_ratio;
72
} ThreadVal;
73

    
74
int AudioQueueOffset=0;
75
PacketQueue audioq;
76
PacketQueue videoq;
77
AVPacket AudioPkt, VideoPkt;
78
int quit = 0;
79

    
80
int queue_filling_threshold = 0;
81

    
82
SDL_Surface *screen;
83
SDL_Overlay *yuv_overlay;
84
SDL_Rect    rect;
85
SDL_AudioSpec spec;
86
struct SwsContext *img_convert_ctx = NULL;
87
//SDL_mutex *timing_mutex;
88

    
89
int got_sigint = 0;
90

    
91
long long DeltaTime;
92
short int FirstTimeAudio=1, FirstTime = 1;
93

    
94
int dimAudioQ;
95
float deltaAudioQ;
96
float deltaAudioQError=0;
97

    
98
void packet_queue_init(PacketQueue *q, short int Type) {
99
#ifdef DEBUG_QUEUE
100
        printf("QUEUE: INIT BEGIN: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
101
#endif
102
        memset(q,0,sizeof(PacketQueue));
103
        q->mutex = SDL_CreateMutex();
104
        QueueFillingMode=1;
105
        q->queueType=Type;
106
        q->last_frame_extracted = -1;
107
        q->total_lost_frames = 0;
108
        q->first_pkt= NULL;
109
        //q->last_pkt = NULL;
110
        q->nb_packets = 0;
111
        q->size = 0;
112
        FirstTime = 1;
113
        FirstTimeAudio = 1;
114
#ifdef DEBUG_QUEUE
115
        printf("QUEUE: INIT END: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
116
#endif
117
}
118

    
119
void packet_queue_reset(PacketQueue *q, short int Type) {
120
        AVPacketList *tmp,*tmp1;
121
#ifdef DEBUG_QUEUE
122
        printf("QUEUE: RESET BEGIN: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
123
#endif
124
        SDL_LockMutex(q->mutex);
125

    
126
        tmp = q->first_pkt;
127
        while(tmp) {
128
                tmp1 = tmp;
129
                tmp = tmp->next;
130
                av_free_packet(&(tmp1->pkt));
131
                av_free(tmp1);
132
#ifdef DEBUG_QUEUE
133
        printf("F ");
134
#endif
135
        }
136
#ifdef DEBUG_QUEUE
137
        printf("\n");
138
#endif
139

    
140
        QueueFillingMode=1;
141
        q->last_frame_extracted = -1;
142
        q->total_lost_frames = 0;
143
        q->first_pkt= NULL;
144
        //q->last_pkt = NULL;
145
        q->nb_packets = 0;
146
        q->size = 0;
147
        FirstTime = 1;
148
        FirstTimeAudio = 1;
149
#ifdef DEBUG_QUEUE
150
        printf("QUEUE: RESET END: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
151
#endif
152
        SDL_UnlockMutex(q->mutex);
153
}
154

    
155
int packet_queue_put(PacketQueue *q, AVPacket *pkt) {
156
        short int skip = 0;
157
        AVPacketList *pkt1, *tmp, *prevtmp;
158

    
159
        //make a copy of the incoming packet
160
        if(av_dup_packet(pkt) < 0) {
161
#ifdef DEBUG_QUEUE
162
                printf("QUEUE: PUT in Queue cannot duplicate in packet        : NPackets=%d Type=%d\n",q->nb_packets, q->queueType);
163
#endif
164
                return -1;
165
        }
166
        pkt1 = av_malloc(sizeof(AVPacketList));
167

    
168
        if(!pkt1) {
169
                av_free_packet(pkt);
170
                return -1;
171
        }
172
        pkt1->pkt = *pkt;
173
        pkt1->next = NULL;
174

    
175
        SDL_LockMutex(q->mutex);
176

    
177
        // INSERTION SORT ALGORITHM
178
        // before inserting pkt, check if pkt.stream_index is <= current_extracted_frame.
179
        if(pkt->stream_index > q->last_frame_extracted) {
180
                // either checking starting from the first_pkt or needed other struct like AVPacketList with next and prev....
181
                //if (!q->last_pkt)
182
                if(!q->first_pkt)
183
                        q->first_pkt = pkt1;
184
                else if(pkt->stream_index < q->first_pkt->pkt.stream_index) {
185
                        //the packet that has arrived is earlier than the first we got some time ago!
186
                        //we need to put it at the head of the queue
187
                        pkt1->next = q->first_pkt;
188
                        q->first_pkt = pkt1;
189
                }
190
                else {
191
                        tmp = q->first_pkt;
192
                        while(tmp->pkt.stream_index < pkt->stream_index) {
193
                                prevtmp = tmp;
194
                                tmp = tmp->next;
195

    
196
                                if(!tmp) {
197
                                        break;
198
                                }
199
                        }
200
                        if(tmp && tmp->pkt.stream_index == pkt->stream_index) {
201
                                //we already have a frame with that index
202
                                skip = 1;
203
#ifdef DEBUG_QUEUE
204
                                printf("QUEUE: PUT: we already have frame with index %d, skipping\n", pkt->stream_index);
205
#endif
206
                        }
207
                        else {
208
                                prevtmp->next = pkt1;
209
                                pkt1->next = tmp;
210
                        }
211
                        //q->last_pkt->next = pkt1; // It was uncommented when not insertion sort
212
                }
213
                if(skip == 0) {
214
                        //q->last_pkt = pkt1;
215
                        q->nb_packets++;
216
                        q->size += pkt1->pkt.size;
217
                        if(q->nb_packets>=queue_filling_threshold && QueueFillingMode) // && q->queueType==AUDIO)
218
                        {
219
                                QueueFillingMode=0;
220
#ifdef DEBUG_QUEUE
221
                                printf("QUEUE: PUT: FillingMode set to zero\n");
222
#endif
223
                        }
224
                }
225
        }
226
        else {
227
                av_free_packet(&pkt1->pkt);
228
                av_free(pkt1);
229
#ifdef DEBUG_QUEUE
230
                                printf("QUEUE: PUT: NOT inserting because index %d > last extracted %d\n", pkt->stream_index, q->last_frame_extracted);
231
#endif
232
        }
233

    
234
        SDL_UnlockMutex(q->mutex);
235
        return 0;
236
}
237

    
238

    
239
int decode_enqueued_audio_packet(AVPacket *pkt, PacketQueue *q) {
240
        uint16_t *audio_bufQ = NULL;
241
        int16_t *dataQ = NULL;
242
        int data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
243
        int lenQ;
244
        int ret = 0;
245

    
246
        //set the flag to decoded anyway        
247
        pkt->convergence_duration = -1;
248

    
249
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
250
        if(audio_bufQ) {
251
#ifdef DEBUG_AUDIO_BUFFER
252
                printf("AUDIO_BUFFER: about to decode packet %d, size %d, data %d\n", pkt->stream_index, pkt->size, pkt->data);
253
#endif
254
                //decode the packet data
255
                lenQ = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_bufQ, &data_sizeQ, pkt);
256
                if(lenQ > 0) {
257
                        dataQ = (int16_t *)av_malloc(data_sizeQ); //this will be free later at the time of playback
258
                        if(dataQ) {
259
                                memcpy(dataQ, audio_bufQ, data_sizeQ);
260
                                //discard the old encoded bytes
261
                                av_free(pkt->data);
262
                                //subtract them from queue size
263
                                q->size -= pkt->size;
264
                                pkt->data = (int8_t *)dataQ;
265
                                pkt->size = data_sizeQ;
266
                                //add new size to queue size
267
                                q->size += pkt->size;
268
                                ret = 1;
269
                        }
270
                        else {
271
#ifdef DEBUG_AUDIO_BUFFER
272
                                printf("AUDIO_BUFFER: cannot alloc space for decoded packet %d\n", pkt->stream_index);
273
#endif
274
                        }
275
                }
276
                else {
277
#ifdef DEBUG_AUDIO_BUFFER
278
                        printf("AUDIO_BUFFER: cannot decode packet %d\n", pkt->stream_index);
279
#endif
280
                }
281
                av_free(audio_bufQ);
282
        }
283
        else {
284
#ifdef DEBUG_AUDIO_BUFFER
285
                printf("AUDIO_BUFFER: cannot alloc decode buffer for packet %d\n", pkt->stream_index);
286
#endif
287
        }
288
        return ret; //problems occurred
289
}
290

    
291

    
292
//removes a packet from the list and returns the next
293
AVPacketList *remove_from_queue(PacketQueue *q, AVPacketList *p) {
294
        AVPacketList *retpk = p->next;
295
        q->nb_packets--;
296
        //adjust size here and not in the various cases of the dequeue
297
        q->size -= p->pkt.size;
298
        if(&p->pkt)
299
                av_free_packet(&p->pkt);
300
        if(p)
301
                av_free(p);
302
        return retpk;
303
}
304

    
305
AVPacketList *seek_and_decode_packet_starting_from(AVPacketList *p, PacketQueue *q) {
306
        while(p) {
307
                        //check if audio packet has been already decoded
308
                        if(p->pkt.convergence_duration == 0) {
309
                                //not decoded yet, try to decode it
310
                                if( !decode_enqueued_audio_packet(&(p->pkt), q) ) {
311
                                        //it was not possible to decode this packet, return next one
312
                                        p = remove_from_queue(q, p);
313
                                }
314
                                else
315
                                        return p;
316
                        }
317
                        else
318
                                return p;
319
        }
320
        return NULL;
321
}
322

    
323
void update_queue_stats(PacketQueue *q, int packet_index) {
324
        //compute lost frame statistics
325
        if(q->last_frame_extracted > 0 && packet_index > q->last_frame_extracted) {
326
                q->total_lost_frames = q->total_lost_frames + packet_index - q->last_frame_extracted - 1;
327
#ifdef DEBUG_STATS
328
                printf("  STATS QUEUE stats: stidx %d last %d tot %d\n", packet_index, q->last_frame_extracted, q->total_lost_frames);
329
#endif
330
        }
331
}
332

    
333
int packet_queue_get(PacketQueue *q, AVPacket *pkt, short int av) {
334
        //AVPacket tmp;
335
        AVPacketList *pkt1 = NULL;
336
        int ret=-1;
337
        int SizeToCopy=0;
338

    
339
        SDL_LockMutex(q->mutex);
340

    
341
#ifdef DEBUG_QUEUE
342
        printf("QUEUE: Get NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
343
#endif
344

    
345
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
346
        {
347
                SDL_UnlockMutex(q->mutex);
348
                return -1;
349
        }
350

    
351
        if(av==1) { //somebody requested an audio packet, q is the audio queue
352
                //try to dequeue the first packet of the audio queue
353
                pkt1 = seek_and_decode_packet_starting_from(q->first_pkt, q);
354
                if(pkt1) { //yes we have them!
355
                        if(pkt1->pkt.size-AudioQueueOffset > dimAudioQ) {
356
                                //one packet if enough to give us the requested number of bytes by the audio_callback
357
#ifdef DEBUG_QUEUE
358
                                printf("  AV=1 and Extract from the same packet\n");
359
#endif
360
                                pkt->size = dimAudioQ;
361
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
362
                                pkt->dts = pkt1->pkt.dts;
363
                                pkt->pts = pkt1->pkt.pts;
364
                                pkt->stream_index = pkt1->pkt.stream_index;//1;
365
                                pkt->flags = 1;
366
                                pkt->pos = -1;
367
                                pkt->convergence_duration = -1;
368
#ifdef DEBUG_QUEUE
369
                                printf("   Adjust timestamps Old = %lld New = %lld\n", pkt1->pkt.dts, (int64_t)(pkt1->pkt.dts + deltaAudioQ + deltaAudioQError));
370
#endif
371
                                int64_t Olddts=pkt1->pkt.dts;
372
                                pkt1->pkt.dts += deltaAudioQ + deltaAudioQError;
373
                                pkt1->pkt.pts += deltaAudioQ + deltaAudioQError;
374
                                deltaAudioQError=(float)Olddts + deltaAudioQ + deltaAudioQError - (float)pkt1->pkt.dts;
375
                                AudioQueueOffset += dimAudioQ;
376
#ifdef DEBUG_QUEUE
377
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
378
#endif
379
                                //update overall state of queue
380
                                //size is diminished because we played some audio samples
381
                                //but packet is not removed since a portion has still to be played
382
                                //HINT ERRATA we had a size mismatch since size grows with the
383
                                //number of compressed bytes, and diminishes here with the number
384
                                //of raw uncompressed bytes, hence we update size during the
385
                                //real removes and not here anymore
386
                                //q->size -= dimAudioQ;
387
                                update_queue_stats(q, pkt->stream_index);
388
                                //update index of last frame extracted
389
                                q->last_frame_extracted = pkt->stream_index;
390
#ifdef DEBUG_AUDIO_BUFFER
391
                                printf("1: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
392
#endif
393
                                ret = 1; //OK
394
                        }
395
                        else {
396
                                //we need bytes from two consecutive packets to satisfy the audio_callback
397
#ifdef DEBUG_QUEUE
398
                                printf("  AV = 1 and Extract from 2 packets\n");
399
#endif
400
                                //check for a valid next packet since we will finish the current packet
401
                                //and also take some bytes from the next one
402
                                pkt1->next = seek_and_decode_packet_starting_from(pkt1->next, q);
403
                                if(pkt1->next) {
404
#ifdef DEBUG_QUEUE
405
                                        printf("   we have a next...\n");
406
#endif
407
                                        pkt->size = dimAudioQ;
408
                                        pkt->dts = pkt1->pkt.dts;
409
                                        pkt->pts = pkt1->pkt.pts;
410
                                        pkt->stream_index = pkt1->pkt.stream_index;//1;
411
                                        pkt->flags = 1;
412
                                        pkt->pos = -1;
413
                                        pkt->convergence_duration = -1;
414
                                        {
415
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
416
#ifdef DEBUG_QUEUE
417
                                                printf("      SizeToCopy=%d\n",SizeToCopy);
418
#endif
419
                                                memcpy(pkt->data, pkt1->pkt.data+AudioQueueOffset, SizeToCopy);
420
                                                memcpy(pkt->data+SizeToCopy, pkt1->next->pkt.data, (dimAudioQ-SizeToCopy)*sizeof(uint8_t));
421
                                        }
422
#ifdef DEBUG_AUDIO_BUFFER
423
                                        printf("2: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
424
#endif
425
                                }
426
#ifdef DEBUG_AUDIO_BUFFER
427
                                else {
428
                                        printf("2: NONEXT\n");
429
                                }
430
#endif
431
                                //HINT SEE before q->size -= SizeToCopy;
432
                                q->first_pkt = remove_from_queue(q, pkt1);
433

    
434
                                // Adjust timestamps
435
                                pkt1 = q->first_pkt;
436
                                if(pkt1) {
437
                                        int Offset=(dimAudioQ-SizeToCopy)*1000/(spec.freq*2*spec.channels);
438
                                        int64_t LastDts=pkt1->pkt.dts;
439
                                        pkt1->pkt.dts += Offset + deltaAudioQError;
440
                                        pkt1->pkt.pts += Offset + deltaAudioQError;
441
                                        deltaAudioQError = (float)LastDts + (float)Offset + deltaAudioQError - (float)pkt1->pkt.dts;
442
#ifdef DEBUG_QUEUE
443
                                        printf("   Adjust timestamps Old = %lld New = %lld\n", LastDts, pkt1->pkt.dts);
444
#endif
445
                                        AudioQueueOffset = dimAudioQ - SizeToCopy;
446
                                        //SEE BEFORE HINT q->size -= AudioQueueOffset;
447
                                        ret = 1;
448
                                }
449
                                else {
450
                                        AudioQueueOffset=0;
451
#ifdef DEBUG_AUDIO_BUFFER
452
                                        printf("0: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
453
#endif
454
                                }
455
#ifdef DEBUG_QUEUE
456
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
457
#endif
458
                                update_queue_stats(q, pkt->stream_index);
459
                                //update index of last frame extracted
460
                                q->last_frame_extracted = pkt->stream_index;
461
                        }
462
                }
463
        }
464
        else { //somebody requested a video packet, q is the video queue
465
                pkt1 = q->first_pkt;
466
                if(pkt1) {
467
#ifdef DEBUG_QUEUE
468
                        printf("  AV not 1\n");
469
#endif
470
                        pkt->size = pkt1->pkt.size;
471
                        pkt->dts = pkt1->pkt.dts;
472
                        pkt->pts = pkt1->pkt.pts;
473
                        pkt->stream_index = pkt1->pkt.stream_index;
474
                        pkt->flags = pkt1->pkt.flags;
475
                        pkt->pos = pkt1->pkt.pos;
476
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
477
                        //*pkt = pkt1->pkt;
478
                        memcpy(pkt->data, pkt1->pkt.data, pkt1->pkt.size);
479

    
480
                        //HINT SEE BEFORE q->size -= pkt1->pkt.size;
481
                        q->first_pkt = remove_from_queue(q, pkt1);
482

    
483
                        ret = 1;
484
                        update_queue_stats(q, pkt->stream_index);
485
                        //update index of last frame extracted
486
                        q->last_frame_extracted = pkt->stream_index;
487
                }
488
#ifdef DEBUG_QUEUE
489
                else {
490
                        printf("  VIDEO pk1 NULL!!!!\n");
491
                }
492
#endif
493
        }
494

    
495
        if(q->nb_packets==0 && q->queueType==AUDIO) {
496
                QueueFillingMode=1;
497
#ifdef DEBUG_QUEUE
498
                printf("QUEUE: Get FillingMode ON\n");
499
#endif
500
        }
501
#ifdef DEBUG_QUEUE
502
        printf("QUEUE: Get LastFrameExtracted = %d\n",q->last_frame_extracted);
503
        printf("QUEUE: Get Tot lost frames = %d\n",q->total_lost_frames);
504
#endif
505

    
506
        SDL_UnlockMutex(q->mutex);
507
        return ret;
508
}
509

    
510

    
511
int audio_decode_frame(uint8_t *audio_buf, int buf_size) {
512
        //struct timeval now;
513
        int audio_pkt_size = 0;
514
        long long Now;
515
        short int DecodeAudio=0, SkipAudio=0;
516
        //int len1, data_size;
517

    
518
        //gettimeofday(&now,NULL);
519
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
520
        Now=(long long)SDL_GetTicks();
521

    
522
        if(QueueFillingMode || QueueStopped)
523
        {
524
                //SDL_LockMutex(timing_mutex);
525
                FirstTimeAudio=1;
526
                FirstTime = 1;
527
                //SDL_UnlockMutex(timing_mutex);
528
                return -1;
529
        }
530

    
531
        if((FirstTime==1 || FirstTimeAudio==1) && audioq.size>0) {
532
                if(audioq.first_pkt->pkt.pts>0)
533
                {
534
                        //SDL_LockMutex(timing_mutex);
535
                        DeltaTime=Now-(long long)(audioq.first_pkt->pkt.pts);
536
                        FirstTimeAudio = 0;
537
                        FirstTime = 0;
538
                        //SDL_UnlockMutex(timing_mutex);
539
#ifdef DEBUG_AUDIO 
540
                         printf("AUDIO: audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTime);
541
#endif
542
                }
543
        }
544

    
545
#ifdef DEBUG_AUDIO 
546
        if(audioq.first_pkt)
547
        {
548
                printf("AUDIO: audio_decode_frame - Syncro params: Delta:%lld Now:%lld pts=%lld pts+Delta=%lld ",(long long)DeltaTime,Now,(long long)audioq.first_pkt->pkt.pts,(long long)audioq.first_pkt->pkt.pts+DeltaTime);
549
                printf("AUDIO: QueueLen=%d ",(int)audioq.nb_packets);
550
                printf("AUDIO: QueueSize=%d\n",(int)audioq.size);
551
        }
552
        else
553
                printf("AUDIO: audio_decode_frame - Empty queue\n");
554
#endif
555

    
556

    
557
        if(audioq.nb_packets>0) {
558
                if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
559
                        SkipAudio = 1;
560
                        DecodeAudio = 0;
561
                }
562
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
563
                        (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
564
                                SkipAudio = 0;
565
                                DecodeAudio = 1;
566
                }
567
        }
568
                
569
        while(SkipAudio==1 && audioq.size>0) {
570
                SkipAudio = 0;
571
#ifdef DEBUG_AUDIO
572
                 printf("AUDIO: skipaudio: queue size=%d\n",audioq.size);
573
#endif
574
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
575
                        return -1;
576
                }
577
                if(audioq.first_pkt)
578
                {
579
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
580
                                SkipAudio = 1;
581
                                DecodeAudio = 0;
582
                        }
583
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
584
                                (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
585
                                        SkipAudio = 0;
586
                                        DecodeAudio = 1;
587
                        }
588
                }
589
        }
590
        if(DecodeAudio==1) {
591
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
592
                        return -1;
593
                }
594
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
595
                audio_pkt_size = AudioPkt.size;
596
#ifdef DEBUG_AUDIO
597
                 printf("AUDIO: Decode audio\n");
598
#endif
599
        }
600

    
601
        return audio_pkt_size;
602
}
603

    
604

    
605
int video_callback(void *valthread) {
606
        //AVPacket pktvideo;
607
        AVCodecContext  *pCodecCtx;
608
        AVCodec         *pCodec;
609
        AVFrame         *pFrame;
610
        AVPacket        packet;
611
        int frameFinished;
612
        int countexit;
613
        AVPicture pict;
614
        //FILE *frecon;
615
        SDL_Event event;
616
        long long Now;
617
        short int SkipVideo, DecodeVideo;
618

    
619
        //double frame_rate = 0.0,time_between_frames=0.0;
620
        //struct timeval now;
621

    
622
        //int wait_for_sync = 1;
623
        ThreadVal *tval;
624
        tval = (ThreadVal *)valthread;
625

    
626
        //frame_rate = tval->framerate;
627
        //time_between_frames = 1.e6 / frame_rate;
628
        //gettimeofday(&time_now,0);
629

    
630
        //frecon = fopen("recondechunk.mpg","wb");
631

    
632
        pCodecCtx=avcodec_alloc_context();
633
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
634
#ifdef H264_VIDEO_ENCODER
635
        pCodecCtx->codec_id  = CODEC_ID_H264;
636
        pCodecCtx->me_range = 16;
637
        pCodecCtx->max_qdiff = 4;
638
        pCodecCtx->qmin = 10;
639
        pCodecCtx->qmax = 51;
640
        pCodecCtx->qcompress = 0.6;
641
#else
642
        pCodecCtx->codec_id  = CODEC_ID_MPEG4;
643
#endif
644
        //pCodecCtx->bit_rate = 400000;
645
        // resolution must be a multiple of two
646
        pCodecCtx->width = tval->width;//176;//352;
647
        pCodecCtx->height = tval->height;//144;//288;
648
        // frames per second
649
        //pCodecCtx->time_base = (AVRational){1,25};
650
        //pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
651
        //pCodecCtx->max_b_frames=1;
652
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
653
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
654

    
655
        if(pCodec==NULL) {
656
                fprintf(stderr, "Unsupported codec!\n");
657
                return -1; // Codec not found
658
        }
659
        if(avcodec_open(pCodecCtx, pCodec) < 0) {
660
                fprintf(stderr, "could not open codec\n");
661
                return -1; // Could not open codec
662
        }
663
        pFrame=avcodec_alloc_frame();
664
        if(pFrame==NULL) {
665
                printf("Memory error!!!\n");
666
                return -1;
667
        }
668

    
669
        while(!quit) {
670
                if(QueueFillingMode || QueueStopped)
671
                {
672
                        //SDL_LockMutex(timing_mutex);
673
                        FirstTime = 1;
674
                        //SDL_UnlockMutex(timing_mutex);
675
                        usleep(5000);
676
                        continue;
677
                }
678

    
679
                DecodeVideo = 0;
680
                SkipVideo = 0;
681
                Now=(long long)SDL_GetTicks();
682
                if(FirstTime==1 && videoq.size>0) {
683
                        if(videoq.first_pkt->pkt.pts>0)
684
                        {
685
                                //SDL_LockMutex(timing_mutex);
686
                                DeltaTime=Now-(long long)videoq.first_pkt->pkt.pts;
687
                                FirstTime = 0;
688
                                //SDL_UnlockMutex(timing_mutex);
689
                        }
690
#ifdef DEBUG_VIDEO 
691
                         printf("VIDEO: VideoCallback - DeltaTimeAudio=%lld\n",DeltaTime);
692
#endif
693
                }
694

    
695
#ifdef DEBUG_VIDEO 
696
                if(videoq.first_pkt)
697
                {
698
                        printf("VIDEO: VideoCallback - Syncro params: Delta:%lld Now:%lld pts=%lld pts+Delta=%lld ",(long long)DeltaTime,Now,(long long)videoq.first_pkt->pkt.pts,(long long)videoq.first_pkt->pkt.pts+DeltaTime);
699
                        printf("VIDEO: Index=%d ", (int)videoq.first_pkt->pkt.stream_index);
700
                        printf("VIDEO: QueueLen=%d ", (int)videoq.nb_packets);
701
                        printf("VIDEO: QueueSize=%d\n", (int)videoq.size);
702
                }
703
                else
704
                        printf("VIDEO: VideoCallback - Empty queue\n");
705
#endif
706

    
707
                if(videoq.nb_packets>0) {
708
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)<Now-(long long)MAX_TOLLERANCE) {
709
                                SkipVideo = 1;
710
                                DecodeVideo = 0;
711
                        }
712
                        else 
713
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)>=Now-(long long)MAX_TOLLERANCE &&
714
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTime)<=Now+(long long)MAX_TOLLERANCE) {
715
                                        SkipVideo = 0;
716
                                        DecodeVideo = 1;
717
                                }
718
                }
719
#ifdef DEBUG_VIDEO
720
                printf("VIDEO: skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
721
#endif
722

    
723
                while(SkipVideo==1 && videoq.size>0) {
724
                        SkipVideo = 0;
725
#ifdef DEBUG_VIDEO 
726
                         printf("VIDEO: Skip Video\n");
727
#endif
728
                        if(packet_queue_get(&videoq,&VideoPkt,0) < 0) {
729
                                break;
730
                        }
731
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
732
                        if(videoq.first_pkt)
733
                        {
734
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
735
                                        SkipVideo = 1;
736
                                        DecodeVideo = 0;
737
                                }
738
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
739
                                                                (long long)videoq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
740
                                        SkipVideo = 0;
741
                                        DecodeVideo = 1;
742
                                }
743
                        }
744
                }
745
                
746
                if(DecodeVideo==1) {
747
                        if(packet_queue_get(&videoq,&VideoPkt,0) > 0) {
748

    
749
#ifdef DEBUG_VIDEO
750
                                printf("VIDEO: Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
751
#endif
752

    
753
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
754

    
755
                                if(frameFinished) { // it must be true all the time else error
756
#ifdef DEBUG_VIDEO
757
                                        printf("VIDEO: FrameFinished\n");
758
#endif
759
                                        //SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height, cont++);
760
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
761

    
762
                                        // Lock SDL_yuv_overlay
763
                                        if(SDL_MUSTLOCK(screen)) {
764

    
765
                                                if(SDL_LockSurface(screen) < 0) {
766
                                                        continue;
767
                                                }
768
                                        }
769

    
770
                                        if(SDL_LockYUVOverlay(yuv_overlay) < 0) {
771
                                                if(SDL_MUSTLOCK(screen)) {
772
                                                        SDL_UnlockSurface(screen);
773
                                                }
774
                                                continue;
775
                                        }
776
                                        pict.data[0] = yuv_overlay->pixels[0];
777
                                        pict.data[1] = yuv_overlay->pixels[2];
778
                                        pict.data[2] = yuv_overlay->pixels[1];
779

    
780
                                        pict.linesize[0] = yuv_overlay->pitches[0];
781
                                        pict.linesize[1] = yuv_overlay->pitches[2];
782
                                        pict.linesize[2] = yuv_overlay->pitches[1];
783

    
784
                                        if(img_convert_ctx == NULL) {
785
                                                img_convert_ctx = sws_getContext(tval->width, tval->height, PIX_FMT_YUV420P, rect.w, rect.h, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
786
                                                if(img_convert_ctx == NULL) {
787
                                                        fprintf(stderr, "Cannot initialize the conversion context!\n");
788
                                                        exit(1);
789
                                                }
790
                                        }
791
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
792
                                        sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, tval->height, pict.data, pict.linesize);
793
                                        SDL_UnlockYUVOverlay(yuv_overlay);
794
                                        // Show, baby, show!
795
                                        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
796
                                        if(SDL_MUSTLOCK(screen)) {
797
                                                SDL_UnlockSurface(screen);
798
                                        }
799
                                } //if FrameFinished
800
                        } // if packet_queue_get
801
                } //if DecodeVideo=1
802

    
803
                usleep(5000);
804
        }
805
        av_free(pCodecCtx);
806
        //fclose(frecon);
807
#ifdef DEBUG_VIDEO
808
         printf("VIDEO: video callback end\n");
809
#endif
810
        return 1;
811
}
812

    
813

    
814
void aspect_ratio_rect(float aspect_ratio, int width, int height) {
815
        float aspect = aspect_ratio * (float)width / (float)height;
816
        int h, w, x, y;
817
        h = height;
818
        w = ((int)rint(h * aspect)) & -3;
819
        if(w > width) {
820
                w = width;
821
                h = ((int)rint(w / aspect)) & -3;
822
        }
823
        x = (width - w) / 2;
824
        y = (height - h) / 2;
825
        rect.x = 0;//x;
826
        rect.y = 0;//y;
827
        rect.w = w;
828
        rect.h = h;
829
}
830

    
831

    
832
void audio_callback(void *userdata, Uint8 *stream, int len) {
833

    
834
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
835
        int audio_size;
836

    
837
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
838

    
839
        audio_size = audio_decode_frame(audio_buf, sizeof(audio_buf));
840
        if(audio_size != len) {
841
                memset(stream, 0, len);
842
        } else {
843
                memcpy(stream, (uint8_t *)audio_buf, len);
844
        }
845
}
846

    
847
void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
848
        SDL_Surface *image;
849
        SDL_Rect dest;
850

    
851
        /* Load a BMP file on a surface */
852
        image = SDL_LoadBMP(file);
853
        if ( image == NULL ) {
854
                fprintf(stderr, "Error loading %s: %s\n", file, SDL_GetError());
855
                return;
856
        }
857

    
858
        /* Copy on the screen surface 
859
        surface should be blocked now.
860
        */
861
        dest.x = x;
862
        dest.y = y;
863
        dest.w = image->w;
864
        dest.h = image->h;
865
        SDL_BlitSurface(image, NULL, screen, &dest);
866

    
867
        /* Update the screen area just changed */
868
        SDL_UpdateRects(screen, 1, &dest);
869
}
870

    
871
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
872
        FILE *pFile;
873
        char szFilename[32];
874
        int  y;
875
  
876
         // Open file
877
        sprintf(szFilename, "frame%d.ppm", iFrame);
878
        pFile=fopen(szFilename, "wb");
879
        if(pFile==NULL)
880
                return;
881
  
882
        // Write header
883
        fprintf(pFile, "P5\n%d %d\n255\n", width, height);
884
  
885
        // Write pixel data
886
        for(y=0; y<height; y++)
887
                  fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
888
  
889
        // Close file
890
        fclose(pFile);
891
}
892

    
893
void sigint_handler (int signal) {
894
        printf("Caught SIGINT, exiting...");
895
        got_sigint = 1;
896
}
897

    
898
void ProcessKeys() {
899
        static Uint32 LastTime=0;
900
        static int LastKey=-1;
901

    
902
        Uint32 Now=SDL_GetTicks();
903
        Uint8* keystate=SDL_GetKeyState(NULL);
904
        if(keystate[SDLK_SPACE] &&
905
          (LastKey!=SDLK_SPACE || (LastKey==SDLK_SPACE && (Now-LastTime>1000))))
906
        {
907
                LastKey=SDLK_SPACE;
908
                LastTime=Now;
909
                QueueStopped=!QueueStopped;
910
        }
911
        if(keystate[SDLK_ESCAPE] &&
912
          (LastKey!=SDLK_ESCAPE || (LastKey==SDLK_ESCAPE && (Now-LastTime>1000))))
913
        {
914
                LastKey=SDLK_ESCAPE;
915
                LastTime=Now;
916
                quit=1;
917
        }
918
        /*if(keystate[SDLK_f] &&
919
          (LastKey!=SDLK_f || (LastKey==SDLK_f && (Now-LastTime>1000))))
920
        {
921
                LastKey=SDLK_f;
922
                LastTime=Now;
923
                SDL_WM_ToggleFullScreen(NULL);
924
        }*/
925
}
926

    
927
int main(int argc, char *argv[]) {
928
        int i, j, videoStream, outbuf_size, out_size, out_size_audio, seq_current_chunk = 0, audioStream;
929
        int len1, data_size, stime, cont=0;
930
        int frameFinished, len_audio;
931
        int numBytes, outbuf_audio_size, audio_size;
932

    
933
        int y;
934
        
935
        uint8_t *outbuf,*outbuf_audio;
936
        uint8_t *outbuf_audi_audio;
937
        
938
        AVFormatContext *pFormatCtx;
939

    
940
        AVCodec         *pCodec,*aCodec;
941
        AVFrame         *pFrame; 
942

    
943
        AVPicture pict;
944
        SDL_Thread *video_thread;//exit_thread,*exit_thread2;
945
        SDL_Event event;
946
        SDL_AudioSpec wanted_spec;
947
        
948
        struct MHD_Daemon *daemon = NULL;        
949

    
950
        char buf[1024],outfile[1024], basereadfile[1024],readfile[1024];
951
        FILE *fp;        
952
        int width,height,asample_rate,achannels;
953
        float ratio;
954

    
955
        ThreadVal *tval;
956
        tval = (ThreadVal *)malloc(sizeof(ThreadVal));
957
                
958
        if(argc<7) {
959
                printf("chunker_player width height aspect_ratio audio_sample_rate audio_channels queue_thresh\n");
960
                exit(1);
961
        }
962
        sscanf(argv[1],"%d",&width);
963
        sscanf(argv[2],"%d",&height);
964
        sscanf(argv[3],"%f",&ratio);
965
        sscanf(argv[4],"%d",&asample_rate);
966
        sscanf(argv[5],"%d",&achannels);
967
        sscanf(argv[6],"%d",&queue_filling_threshold);
968
        tval->width = width;
969
        tval->height = height;
970
        tval->aspect_ratio = ratio;
971

    
972
        // Register all formats and codecs
973
        av_register_all();
974
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
975
                fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
976
                return -1;
977
        }
978

    
979
        aCodecCtx = avcodec_alloc_context();
980
        //aCodecCtx->bit_rate = 64000;
981
        aCodecCtx->sample_rate = asample_rate;
982
        aCodecCtx->channels = achannels;
983
#ifdef MP3_AUDIO_ENCODER
984
        aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
985
#else
986
        aCodec = avcodec_find_decoder(CODEC_ID_MP2);
987
#endif
988
        printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
989
        if(!aCodec) {
990
                printf("Codec not found!\n");
991
                return -1;
992
        }
993
        if(avcodec_open(aCodecCtx, aCodec)<0) {
994
                fprintf(stderr, "could not open codec\n");
995
                return -1; // Could not open codec
996
        }
997
        printf("using audio Codecid: %d ",aCodecCtx->codec_id);
998
        printf("samplerate: %d ",aCodecCtx->sample_rate);
999
        printf("channels: %d\n",aCodecCtx->channels);
1000
        wanted_spec.freq = aCodecCtx->sample_rate;
1001
        wanted_spec.format = AUDIO_S16SYS;
1002
        wanted_spec.channels = aCodecCtx->channels;
1003
        wanted_spec.silence = 0;
1004
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1005
        wanted_spec.callback = audio_callback;
1006
        wanted_spec.userdata = aCodecCtx;
1007
        if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
1008
                fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
1009
                return -1;
1010
        }
1011
        dimAudioQ = spec.size;
1012
        deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
1013

    
1014
#ifdef DEBUG_AUDIO
1015
        printf("freq:%d\n",spec.freq);
1016
        printf("format:%d\n",spec.format);
1017
        printf("channels:%d\n",spec.channels);
1018
        printf("silence:%d\n",spec.silence);
1019
        printf("samples:%d\n",spec.samples);
1020
        printf("size:%d\n",spec.size);
1021
        printf("deltaAudioQ: %f\n",deltaAudioQ);
1022
#endif
1023

    
1024
        pFrame=avcodec_alloc_frame();
1025
        if(pFrame==NULL) {
1026
                printf("Memory error!!!\n");
1027
                return -1;
1028
        }
1029
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1030

    
1031
        //initialize the audio and the video queues
1032
        packet_queue_init(&audioq, AUDIO);
1033
        packet_queue_init(&videoq, VIDEO);
1034

    
1035
        //calculate aspect ratio and put updated values in rect
1036
        aspect_ratio_rect(ratio, width, height);
1037

    
1038
        SDL_WM_SetCaption("Filling buffer...", NULL);
1039
        // Make a screen to put our video
1040
#ifndef __DARWIN__
1041
        screen = SDL_SetVideoMode(rect.w, rect.h, 0, 0);
1042
#else
1043
        screen = SDL_SetVideoMode(rect.w, rect.h, 24, 0);
1044
#endif
1045
        if(!screen) {
1046
                fprintf(stderr, "SDL: could not set video mode - exiting\n");
1047
                exit(1);
1048
        }
1049

    
1050
        //create video overlay for display of video frames
1051
        yuv_overlay = SDL_CreateYUVOverlay(rect.w, rect.h, SDL_YV12_OVERLAY, screen);
1052

    
1053
        if ( yuv_overlay == NULL ) {
1054
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
1055
                exit(1);
1056
        }
1057

    
1058
        if ( yuv_overlay->hw_overlay )
1059
                fprintf(stderr,"SDL: Using hardware overlay.");
1060

    
1061
        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
1062

    
1063
        // Init audio and video buffers
1064
        av_init_packet(&AudioPkt);
1065
        av_init_packet(&VideoPkt);
1066
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1067
        if(!AudioPkt.data) return 0;
1068
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
1069
        if(!VideoPkt.data) return 0;
1070
        
1071
        SDL_PauseAudio(0);
1072
        video_thread = SDL_CreateThread(video_callback,tval);
1073

    
1074
        //this thread fetches chunks from the network by listening to the following path, port
1075
        daemon = initChunkPuller(UL_DEFAULT_EXTERNALPLAYER_PATH, UL_DEFAULT_EXTERNALPLAYER_PORT);
1076

    
1077
        // Wait for user input
1078
        while(!quit) {
1079
                if(QueueFillingMode) {
1080
                        SDL_WM_SetCaption("Filling buffer...", NULL);
1081

    
1082
                        if(audioq.nb_packets==0 && audioq.last_frame_extracted>0) {        // video ended therefore init queues
1083
#ifdef DEBUG_QUEUE
1084
                                printf("QUEUE: MAIN SHOULD RESET\n");
1085
#endif
1086
                                packet_queue_reset(&audioq, AUDIO);
1087
                                packet_queue_reset(&videoq, VIDEO);
1088
                        }
1089

    
1090
#ifdef DEBUG_QUEUE
1091
                        //printf("QUEUE: MAIN audio:%d video:%d audiolastframe:%d videolastframe:%d\n", audioq.nb_packets, videoq.nb_packets, audioq.last_frame_extracted, videoq.last_frame_extracted);
1092
#endif
1093
                }
1094
                else
1095
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
1096

    
1097
                //listen for key and mouse
1098
                while(SDL_PollEvent(&event)) {
1099
                                switch(event.type) {
1100
                                        case SDL_QUIT:
1101
                                                //exit(0);
1102
                                                quit=1;
1103
                                        break;
1104
                                }
1105
                                ProcessKeys();
1106
                }
1107
                usleep(120000);
1108
        }
1109

    
1110
        //TERMINATE
1111
        // Stop audio&video playback
1112
        SDL_WaitThread(video_thread,NULL);
1113
        SDL_PauseAudio(1);
1114
        SDL_CloseAudio();
1115
        //SDL_DestroyMutex(timing_mutex);
1116
        SDL_Quit();
1117
        av_free(aCodecCtx);
1118
        free(AudioPkt.data);
1119
        free(VideoPkt.data);
1120
        free(outbuf_audio);
1121
        finalizeChunkPuller(daemon);
1122
        free(tval);
1123
        return 0;
1124
}
1125

    
1126

    
1127

    
1128
int enqueueBlock(const uint8_t *block, const int block_size) {
1129
        Chunk *gchunk = NULL;
1130
        ExternalChunk *echunk = NULL;
1131
        int decoded_size = -1;
1132
        uint8_t *tempdata, *buffer;
1133
        int i, j;
1134
        Frame *frame = NULL;
1135
        AVPacket packet, packetaudio;
1136

    
1137
        uint16_t *audio_bufQ = NULL;
1138
        int16_t *dataQ = NULL;
1139
        int data_sizeQ;
1140
        int lenQ;
1141

    
1142
        //the frame.h gets encoded into 5 slots of 32bits (3 ints plus 2 more for the timeval struct
1143
        static int sizeFrameHeader = 5*sizeof(int32_t);
1144
        static int ExternalChunk_header_size = 5*CHUNK_TRANSCODING_INT_SIZE + 2*CHUNK_TRANSCODING_INT_SIZE + 2*CHUNK_TRANSCODING_INT_SIZE + 1*CHUNK_TRANSCODING_INT_SIZE*2;
1145

    
1146
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1147
        if(!audio_bufQ) {
1148
                printf("Memory error in audio_bufQ!\n");
1149
                return PLAYER_FAIL_RETURN;
1150
        }
1151

    
1152
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1153
        if(!gchunk) {
1154
                printf("Memory error in gchunk!\n");
1155
                av_free(audio_bufQ);
1156
                return PLAYER_FAIL_RETURN;
1157
        }
1158

    
1159
        decoded_size = decodeChunk(gchunk, block, block_size);
1160
#ifdef DEBUG_CHUNKER
1161
        printf("CHUNKER: enqueueBlock: decoded_size %d target size %d\n", decoded_size, GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size);
1162
#endif
1163
  if(decoded_size < 0 || decoded_size != GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size) {
1164
                //HINT here i should differentiate between various return values of the decode
1165
                //in order to free what has been allocated there
1166
                printf("chunk probably corrupted!\n");
1167
                av_free(audio_bufQ);
1168
                free(gchunk);
1169
                return PLAYER_FAIL_RETURN;
1170
        }
1171

    
1172
        echunk = grapesChunkToExternalChunk(gchunk);
1173
        if(echunk == NULL) {
1174
                printf("Memory error in echunk!\n");
1175
                free(gchunk->attributes);
1176
                free(gchunk->data);
1177
                free(gchunk);
1178
                return PLAYER_FAIL_RETURN;
1179
        }
1180
        free(gchunk->attributes);
1181
        free(gchunk);
1182

    
1183
        frame = (Frame *)malloc(sizeof(Frame));
1184
        if(!frame) {
1185
                printf("Memory error in Frame!\n");
1186
                if(gchunk->attributes)
1187
                        free(gchunk->attributes);
1188
                if(echunk->data)
1189
                        free(echunk->data);
1190
                if(echunk)
1191
                        free(echunk);
1192
                av_free(audio_bufQ);
1193
                return PLAYER_FAIL_RETURN;
1194
        }
1195

    
1196
        tempdata = echunk->data; //let it point to first frame of payload
1197
        j=echunk->payload_len;
1198
        while(j>0 && !quit) {
1199
                frame->number = bit32_encoded_pull(tempdata);
1200
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1201
                frame->timestamp.tv_sec = bit32_encoded_pull(tempdata);
1202
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1203
                frame->timestamp.tv_usec = bit32_encoded_pull(tempdata);
1204
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1205
                frame->size = bit32_encoded_pull(tempdata);
1206
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1207
                frame->type = bit32_encoded_pull(tempdata);
1208
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1209

    
1210
                buffer = tempdata; // here coded frame information
1211
                tempdata += frame->size; //let it point to the next frame
1212

    
1213
                if(frame->type < 5) { // video frame
1214
                        av_init_packet(&packet);
1215
                        packet.data = buffer;//video_bufQ;
1216
                        packet.size = frame->size;
1217
                        packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1218
                        packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1219
                        packet.stream_index = frame->number; // use of stream_index for number frame
1220
                        //packet.duration = frame->timestamp.tv_sec;
1221
                        if(packet.size > 0)
1222
                                packet_queue_put(&videoq, &packet); //the _put makes a copy of the packet
1223

    
1224
#ifdef DEBUG_SOURCE
1225
                        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);
1226
#endif
1227
                }
1228
                else if(frame->type == 5) { // audio frame
1229
                        av_init_packet(&packetaudio);
1230
                        packetaudio.data = buffer;
1231
                        packetaudio.size = frame->size;
1232
                        packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1233
                        packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1234
                        //packetaudio.duration = frame->timestamp.tv_sec;
1235
                        packetaudio.stream_index = frame->number; // use of stream_index for number frame
1236
                        packetaudio.flags = 1;
1237
                        packetaudio.pos = -1;
1238

    
1239
                        //instead of -1, in order to signal it is not decoded yet
1240
                        packetaudio.convergence_duration = 0;
1241

    
1242
                        // insert the audio frame into the queue
1243
                        if(packetaudio.size > 0)
1244
                                packet_queue_put(&audioq, &packetaudio);//makes a copy of the packet so i can free here
1245

    
1246
#ifdef DEBUG_SOURCE
1247
                        printf("SOURCE: Insert audio in queue pts=%lld sindex:%d\n", packetaudio.pts, packetaudio.stream_index);
1248
#endif
1249
                }
1250
                else {
1251
                        printf("SOURCE: Unknown frame type %d. Size %d\n", frame->type, frame->size);
1252
                }
1253
                if(frame->size > 0)
1254
                        j = j - sizeFrameHeader - frame->size;
1255
                else {
1256
                        printf("SOURCE: Corrupt frames (size %d) in chunk. Skipping it...\n", frame->size);
1257
                        j = -1;
1258
                }
1259
        }
1260
        //chunk ingestion terminated!
1261
        if(echunk->data)
1262
                free(echunk->data);
1263
        if(echunk)
1264
                free(echunk);
1265
        if(frame)
1266
                free(frame);
1267
        if(audio_bufQ)
1268
                av_free(audio_bufQ);
1269
}