Statistics
| Branch: | Revision:

chunker-player / chunker_player / player_core.c @ 10c75ef7

History | View | Annotate | Download (32.8 KB)

1
#include "player_defines.h"
2
#include "chunker_player.h"
3
// #include "player_commons.h"
4
#include "player_core.h"
5
#include <assert.h>
6

    
7
void PacketQueueInit(PacketQueue *q, short int Type)
8
{
9
#ifdef DEBUG_QUEUE
10
        printf("QUEUE: INIT BEGIN: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
11
#endif
12
        memset(q,0,sizeof(PacketQueue));
13
        q->mutex = SDL_CreateMutex();
14
        QueueFillingMode=1;
15
        q->queueType=Type;
16
        q->last_frame_extracted = -1;
17
        q->total_lost_frames = 0;
18
        q->first_pkt= NULL;
19
        //q->last_pkt = NULL;
20
        q->nb_packets = 0;
21
        q->size = 0;
22
        q->density= 0.0;
23
        FirstTime = 1;
24
        FirstTimeAudio = 1;
25
#ifdef DEBUG_QUEUE
26
        printf("QUEUE: INIT END: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
27
#endif
28
}
29

    
30
void PacketQueueReset(PacketQueue *q, short int Type)
31
{
32
        AVPacketList *tmp,*tmp1;
33
#ifdef DEBUG_QUEUE
34
        printf("QUEUE: RESET BEGIN: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
35
#endif
36
        SDL_LockMutex(q->mutex);
37

    
38
        tmp = q->first_pkt;
39
        while(tmp) {
40
                tmp1 = tmp;
41
                tmp = tmp->next;
42
                av_free_packet(&(tmp1->pkt));
43
                av_free(tmp1);
44
#ifdef DEBUG_QUEUE
45
                printf("F ");
46
#endif
47
        }
48
#ifdef DEBUG_QUEUE
49
        printf("\n");
50
#endif
51

    
52
        QueueFillingMode=1;
53
        q->last_frame_extracted = -1;
54
        q->total_lost_frames = 0;
55
        q->first_pkt= NULL;
56
        //q->last_pkt = NULL;
57
        q->nb_packets = 0;
58
        q->size = 0;
59
        q->density= 0.0;
60
        FirstTime = 1;
61
        FirstTimeAudio = 1;
62
#ifdef DEBUG_QUEUE
63
        printf("QUEUE: RESET END: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
64
#endif
65
        SDL_UnlockMutex(q->mutex);
66
}
67

    
68
int ChunkerPlayerCore_PacketQueuePut(PacketQueue *q, AVPacket *pkt)
69
{
70
        short int skip = 0;
71
        AVPacketList *pkt1, *tmp, *prevtmp;
72
/*
73
        if(q->nb_packets > QUEUE_MAX_SIZE) {
74
#ifdef DEBUG_QUEUE
75
                printf("QUEUE: PUT i have TOO MANY packets %d Type=%d\n", q->nb_packets, q->queueType);
76
#endif    
77
                return -1;
78
  }
79
*/
80
        //make a copy of the incoming packet
81
        if(av_dup_packet(pkt) < 0) {
82
#ifdef DEBUG_QUEUE
83
                printf("QUEUE: PUT in Queue cannot duplicate in packet        : NPackets=%d Type=%d\n",q->nb_packets, q->queueType);
84
#endif
85
                return -1;
86
        }
87
        pkt1 = av_malloc(sizeof(AVPacketList));
88

    
89
        if(!pkt1) {
90
                av_free_packet(pkt);
91
                return -1;
92
        }
93
        pkt1->pkt = *pkt;
94
        pkt1->next = NULL;
95

    
96
        SDL_LockMutex(q->mutex);
97

    
98
        // INSERTION SORT ALGORITHM
99
        // before inserting pkt, check if pkt.stream_index is <= current_extracted_frame.
100
//        if(pkt->stream_index > q->last_frame_extracted) {
101
                // either checking starting from the first_pkt or needed other struct like AVPacketList with next and prev....
102
                //if (!q->last_pkt)
103
                if(!q->first_pkt) {
104
                        q->first_pkt = pkt1;
105
                        q->last_pkt = pkt1;
106
                }
107
                else if(pkt->stream_index < q->first_pkt->pkt.stream_index) {
108
                        //the packet that has arrived is earlier than the first we got some time ago!
109
                        //we need to put it at the head of the queue
110
                        pkt1->next = q->first_pkt;
111
                        q->first_pkt = pkt1;
112
                }
113
                else {
114
                        tmp = q->first_pkt;
115
                        while(tmp->pkt.stream_index < pkt->stream_index) {
116
                                prevtmp = tmp;
117
                                tmp = tmp->next;
118

    
119
                                if(!tmp) {
120
                                        break;
121
                                }
122
                        }
123
                        if(tmp && tmp->pkt.stream_index == pkt->stream_index) {
124
                                //we already have a frame with that index
125
                                skip = 1;
126
#ifdef DEBUG_QUEUE
127
                                printf("QUEUE: PUT: we already have frame with index %d, skipping\n", pkt->stream_index);
128
#endif
129
                        }
130
                        else {
131
                                prevtmp->next = pkt1;
132
                                pkt1->next = tmp;
133
                                if(pkt1->next == NULL)
134
                                        q->last_pkt = pkt1;
135
                        }
136
                        //q->last_pkt->next = pkt1; // It was uncommented when not insertion sort
137
                }
138
                if(skip == 0) {
139
                        //q->last_pkt = pkt1;
140
                        q->nb_packets++;
141
                        q->size += pkt1->pkt.size;
142
                        if(q->nb_packets>=queue_filling_threshold && QueueFillingMode) // && q->queueType==AUDIO)
143
                        {
144
                                QueueFillingMode=0;
145
#ifdef DEBUG_QUEUE
146
                                printf("QUEUE: PUT: FillingMode set to zero\n");
147
#endif
148
                        }
149
                }
150
//        }
151
/*
152
        else {
153
                av_free_packet(&pkt1->pkt);
154
                av_free(pkt1);
155
#ifdef DEBUG_QUEUE
156
                                printf("QUEUE: PUT: NOT inserting because index %d > last extracted %d\n", pkt->stream_index, q->last_frame_extracted);
157
#endif
158
        }
159
*/
160
        // minus one means no lost frames estimation
161
        UpdateQueueStats(q, -1);
162

    
163
        SDL_UnlockMutex(q->mutex);
164
        return 0;
165
}
166

    
167
int ChunkerPlayerCore_InitCodecs(int width, int height, int sample_rate, short int audio_channels)
168
{
169
        // some initializations
170
        QueueStopped = 0;
171
        AudioQueueOffset=0;
172
        AVPlaying = 0;
173
        GotSigInt = 0;
174
        FirstTimeAudio=1;
175
        FirstTime = 1;
176
        deltaAudioQError=0;
177
        InitRect = NULL;
178
        img_convert_ctx = NULL;
179
        
180
        SDL_AudioSpec wanted_spec;
181
        
182
        AVFormatContext *pFormatCtx;
183
        AVCodec         *aCodec;
184
        
185
        memset(&VideoCallbackThreadParams, 0, sizeof(ThreadVal));
186
        
187
        VideoCallbackThreadParams.width = width;
188
        VideoCallbackThreadParams.height = height;
189

    
190
        // Register all formats and codecs
191
        av_register_all();
192

    
193
        aCodecCtx = avcodec_alloc_context();
194
        //aCodecCtx->bit_rate = 64000;
195
        aCodecCtx->sample_rate = sample_rate;
196
        aCodecCtx->channels = audio_channels;
197
#ifdef MP3_AUDIO_ENCODER
198
        aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
199
#else
200
        aCodec = avcodec_find_decoder(CODEC_ID_MP2);
201
#endif
202
        printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
203
        if(!aCodec) {
204
                printf("Codec not found!\n");
205
                return -1;
206
        }
207
        if(avcodec_open(aCodecCtx, aCodec)<0) {
208
                fprintf(stderr, "could not open codec\n");
209
                return -1; // Could not open codec
210
        }
211
        printf("using audio Codecid: %d ",aCodecCtx->codec_id);
212
        printf("samplerate: %d ",aCodecCtx->sample_rate);
213
        printf("channels: %d\n",aCodecCtx->channels);
214
        wanted_spec.freq = aCodecCtx->sample_rate;
215
        wanted_spec.format = AUDIO_S16SYS;
216
        wanted_spec.channels = aCodecCtx->channels;
217
        wanted_spec.silence = 0;
218
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
219
        wanted_spec.callback = AudioCallback;
220
        wanted_spec.userdata = aCodecCtx;
221
        if(!SilentMode)
222
                if(SDL_OpenAudio(&wanted_spec,&AudioSpecification)<0) {
223
                        fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
224
                        return -1;
225
                }
226
        dimAudioQ = AudioSpecification.size;
227
        deltaAudioQ = (float)((float)AudioSpecification.samples)*1000/AudioSpecification.freq;
228

    
229
#ifdef DEBUG_AUDIO
230
        printf("freq:%d\n",AudioSpecification.freq);
231
        printf("format:%d\n",AudioSpecification.format);
232
        printf("channels:%d\n",AudioSpecification.channels);
233
        printf("silence:%d\n",AudioSpecification.silence);
234
        printf("samples:%d\n",AudioSpecification.samples);
235
        printf("size:%d\n",AudioSpecification.size);
236
        printf("deltaAudioQ: %f\n",deltaAudioQ);
237
#endif
238

    
239
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
240

    
241
        //initialize the audio and the video queues
242
        PacketQueueInit(&audioq, AUDIO);
243
        PacketQueueInit(&videoq, VIDEO);
244
        
245
        // Init audio and video buffers
246
        av_init_packet(&AudioPkt);
247
        av_init_packet(&VideoPkt);
248
        printf("AVCODEC_MAX_AUDIO_FRAME_SIZE=%d\n", AVCODEC_MAX_AUDIO_FRAME_SIZE);
249
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
250
        if(!AudioPkt.data) return 1;
251
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
252
        if(!VideoPkt.data) return 1;
253
        
254
        InitRect = (SDL_Rect*) malloc(sizeof(SDL_Rect));
255
        if(!InitRect)
256
        {
257
                printf("Memory error!!!\n");
258
                return -1;
259
        }
260
        InitRect->x = OverlayRect.x;
261
        InitRect->y = OverlayRect.y;
262
        InitRect->w = OverlayRect.w;
263
        InitRect->h = OverlayRect.h;
264
        
265
        return 0;
266
}
267

    
268
int DecodeEnqueuedAudio(AVPacket *pkt, PacketQueue *q)
269
{
270
        uint16_t *audio_bufQ = NULL;
271
        int16_t *dataQ = NULL;
272
        int data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
273
        int lenQ;
274
        int ret = 0;
275

    
276
        //set the flag to decoded anyway        
277
        pkt->convergence_duration = -1;
278

    
279
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
280
        if(audio_bufQ) {
281
#ifdef DEBUG_AUDIO_BUFFER
282
                printf("AUDIO_BUFFER: about to decode packet %d, size %d, data %d\n", pkt->stream_index, pkt->size, pkt->data);
283
#endif
284
                //decode the packet data
285
                lenQ = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_bufQ, &data_sizeQ, pkt);
286
                if(lenQ > 0) {
287
                        dataQ = (int16_t *)av_malloc(data_sizeQ); //this will be free later at the time of playback
288
                        if(dataQ) {
289
                                memcpy(dataQ, audio_bufQ, data_sizeQ);
290
                                //discard the old encoded bytes
291
                                av_free(pkt->data);
292
                                //subtract them from queue size
293
                                q->size -= pkt->size;
294
                                pkt->data = (int8_t *)dataQ;
295
                                pkt->size = data_sizeQ;
296
                                //add new size to queue size
297
                                q->size += pkt->size;
298
                                ret = 1;
299
                        }
300
                        else {
301
#ifdef DEBUG_AUDIO_BUFFER
302
                                printf("AUDIO_BUFFER: cannot alloc space for decoded packet %d\n", pkt->stream_index);
303
#endif
304
                        }
305
                }
306
                else {
307
#ifdef DEBUG_AUDIO_BUFFER
308
                        printf("AUDIO_BUFFER: cannot decode packet %d\n", pkt->stream_index);
309
#endif
310
                }
311
                av_free(audio_bufQ);
312
        }
313
        else {
314
#ifdef DEBUG_AUDIO_BUFFER
315
                printf("AUDIO_BUFFER: cannot alloc decode buffer for packet %d\n", pkt->stream_index);
316
#endif
317
        }
318
        return ret; //problems occurred
319
}
320

    
321
/**
322
 * removes a packet from the list and returns the next
323
 * */
324
AVPacketList *RemoveFromQueue(PacketQueue *q, AVPacketList *p)
325
{
326
        AVPacketList *retpk = p->next;
327
        q->nb_packets--;
328
        //adjust size here and not in the various cases of the dequeue
329
        q->size -= p->pkt.size;
330
        if(&p->pkt)
331
                av_free_packet(&p->pkt);
332
        if(p)
333
                av_free(p);
334
        return retpk;
335
}
336

    
337
AVPacketList *SeekAndDecodePacketStartingFrom(AVPacketList *p, PacketQueue *q)
338
{
339
        while(p) {
340
                        //check if audio packet has been already decoded
341
                        if(p->pkt.convergence_duration == 0) {
342
                                //not decoded yet, try to decode it
343
                                if( !DecodeEnqueuedAudio(&(p->pkt), q) ) {
344
                                        //it was not possible to decode this packet, return next one
345
                                        p = RemoveFromQueue(q, p);
346
                                }
347
                                else
348
                                        return p;
349
                        }
350
                        else
351
                                return p;
352
        }
353
        return NULL;
354
}
355

    
356
void UpdateQueueStats(PacketQueue *q, int packet_index)
357
{
358
        static int N = 50;
359
        
360
        if(q == NULL)
361
                return;
362
        if(q->first_pkt == NULL)
363
                return;
364
        if(q->last_pkt == NULL)
365
                return;
366
        
367
        // assert(q != NULL);
368
        // assert(q->last_pkt != NULL);
369
        // assert(q->first_pkt != NULL);
370
        
371
        if(q->last_pkt->pkt.stream_index > q->first_pkt->pkt.stream_index)
372
                q->density = (double)q->nb_packets / (double)(q->last_pkt->pkt.stream_index - q->first_pkt->pkt.stream_index) * 100.0;
373
        
374
#ifdef DEBUG_STATS
375
        if(q->queueType == AUDIO)
376
                printf("STATS: AUDIO QUEUE DENSITY percentage %f\n", q->density);
377
        if(q->queueType == VIDEO)
378
                printf("STATS: VIDEO QUEUE DENSITY percentage %f\n", q->density);
379
#endif
380
        
381
        if(packet_index != -1)
382
        {
383
                double percentage = 0.0;        
384
                //compute lost frame statistics
385
                if(q->last_frame_extracted > 0 && packet_index > q->last_frame_extracted)
386
                {
387
                        int lost_frames = packet_index - q->last_frame_extracted - 1;
388
                        q->total_lost_frames += lost_frames ;
389
                        percentage = (double)q->total_lost_frames / (double)q->last_frame_extracted * 100.0;
390
                        
391
                        q->loss_history[q->history_index] = lost_frames;
392
                        q->history_index = (q->history_index+1)%N;
393
                        
394
                        int i;
395
                        q->instant_lost_frames = 0;
396
                        for(i=0; i<N; i++)
397
                                q->instant_lost_frames += q->loss_history[i];
398
                        
399
#ifdef DEBUG_STATS
400
                        if(q->queueType == AUDIO)
401
                                printf("STATS: AUDIO FRAMES LOST: instant %d, total %d, total percentage %f\n", q->instant_lost_frames, q->total_lost_frames, percentage);
402
                        else if(q->queueType == VIDEO)
403
                                printf("STATS: VIDEO FRAMES LOST: instant %d, total %d, total percentage %f\n", q->instant_lost_frames, q->total_lost_frames, percentage);
404
#endif
405
                }
406
        }
407
}
408

    
409
int PacketQueueGet(PacketQueue *q, AVPacket *pkt, short int av) {
410
        //AVPacket tmp;
411
        AVPacketList *pkt1 = NULL;
412
        int ret=-1;
413
        int SizeToCopy=0;
414

    
415
        SDL_LockMutex(q->mutex);
416

    
417
#ifdef DEBUG_QUEUE
418
        printf("QUEUE: Get NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
419
#endif
420

    
421
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
422
        {
423
                SDL_UnlockMutex(q->mutex);
424
                return -1;
425
        }
426

    
427
        if(av==1) { //somebody requested an audio packet, q is the audio queue
428
                //try to dequeue the first packet of the audio queue
429
                pkt1 = SeekAndDecodePacketStartingFrom(q->first_pkt, q);
430
                if(pkt1) { //yes we have them!
431
                        if(pkt1->pkt.size-AudioQueueOffset > dimAudioQ) {
432
                                //one packet if enough to give us the requested number of bytes by the audio_callback
433
#ifdef DEBUG_QUEUE
434
                                printf("  AV=1 and Extract from the same packet\n");
435
#endif
436
                                pkt->size = dimAudioQ;
437
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
438
                                pkt->dts = pkt1->pkt.dts;
439
                                pkt->pts = pkt1->pkt.pts;
440
                                pkt->stream_index = pkt1->pkt.stream_index;//1;
441
                                pkt->flags = 1;
442
                                pkt->pos = -1;
443
                                pkt->convergence_duration = -1;
444
#ifdef DEBUG_QUEUE
445
                                printf("   Adjust timestamps Old = %lld New = %lld\n", pkt1->pkt.dts, (int64_t)(pkt1->pkt.dts + deltaAudioQ + deltaAudioQError));
446
#endif
447
                                int64_t Olddts=pkt1->pkt.dts;
448
                                pkt1->pkt.dts += deltaAudioQ + deltaAudioQError;
449
                                pkt1->pkt.pts += deltaAudioQ + deltaAudioQError;
450
                                deltaAudioQError=(float)Olddts + deltaAudioQ + deltaAudioQError - (float)pkt1->pkt.dts;
451
                                AudioQueueOffset += dimAudioQ;
452
#ifdef DEBUG_QUEUE
453
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
454
#endif
455
                                //update overall state of queue
456
                                //size is diminished because we played some audio samples
457
                                //but packet is not removed since a portion has still to be played
458
                                //HINT ERRATA we had a size mismatch since size grows with the
459
                                //number of compressed bytes, and diminishes here with the number
460
                                //of raw uncompressed bytes, hence we update size during the
461
                                //real removes and not here anymore
462
                                //q->size -= dimAudioQ;
463
                                UpdateQueueStats(q, pkt->stream_index);
464
                                //update index of last frame extracted
465
                                q->last_frame_extracted = pkt->stream_index;
466
#ifdef DEBUG_AUDIO_BUFFER
467
                                printf("1: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
468
#endif
469
                                ret = 1; //OK
470
                        }
471
                        else {
472
                                //we need bytes from two consecutive packets to satisfy the audio_callback
473
#ifdef DEBUG_QUEUE
474
                                printf("  AV = 1 and Extract from 2 packets\n");
475
#endif
476
                                //check for a valid next packet since we will finish the current packet
477
                                //and also take some bytes from the next one
478
                                pkt1->next = SeekAndDecodePacketStartingFrom(pkt1->next, q);
479
                                if(pkt1->next) {
480
#ifdef DEBUG_QUEUE
481
                                        printf("   we have a next...\n");
482
#endif
483
                                        pkt->size = dimAudioQ;
484
                                        pkt->dts = pkt1->pkt.dts;
485
                                        pkt->pts = pkt1->pkt.pts;
486
                                        pkt->stream_index = pkt1->pkt.stream_index;//1;
487
                                        pkt->flags = 1;
488
                                        pkt->pos = -1;
489
                                        pkt->convergence_duration = -1;
490
                                        {
491
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
492
#ifdef DEBUG_QUEUE
493
                                                printf("      SizeToCopy=%d\n",SizeToCopy);
494
#endif
495
                                                memcpy(pkt->data, pkt1->pkt.data+AudioQueueOffset, SizeToCopy);
496
                                                memcpy(pkt->data+SizeToCopy, pkt1->next->pkt.data, (dimAudioQ-SizeToCopy)*sizeof(uint8_t));
497
                                        }
498
#ifdef DEBUG_AUDIO_BUFFER
499
                                        printf("2: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
500
#endif
501
                                }
502
#ifdef DEBUG_AUDIO_BUFFER
503
                                else {
504
                                        printf("2: NONEXT\n");
505
                                }
506
#endif
507
                                //HINT SEE before q->size -= SizeToCopy;
508
                                q->first_pkt = RemoveFromQueue(q, pkt1);
509

    
510
                                // Adjust timestamps
511
                                pkt1 = q->first_pkt;
512
                                if(pkt1) {
513
                                        int Offset=(dimAudioQ-SizeToCopy)*1000/(AudioSpecification.freq*2*AudioSpecification.channels);
514
                                        int64_t LastDts=pkt1->pkt.dts;
515
                                        pkt1->pkt.dts += Offset + deltaAudioQError;
516
                                        pkt1->pkt.pts += Offset + deltaAudioQError;
517
                                        deltaAudioQError = (float)LastDts + (float)Offset + deltaAudioQError - (float)pkt1->pkt.dts;
518
#ifdef DEBUG_QUEUE
519
                                        printf("   Adjust timestamps Old = %lld New = %lld\n", LastDts, pkt1->pkt.dts);
520
#endif
521
                                        AudioQueueOffset = dimAudioQ - SizeToCopy;
522
                                        //SEE BEFORE HINT q->size -= AudioQueueOffset;
523
                                        ret = 1;
524
                                        UpdateQueueStats(q, pkt->stream_index);
525
                                }
526
                                else {
527
                                        AudioQueueOffset=0;
528
#ifdef DEBUG_AUDIO_BUFFER
529
                                        printf("0: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
530
#endif
531
                                }
532
#ifdef DEBUG_QUEUE
533
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
534
#endif
535
                                //update index of last frame extracted
536
                                q->last_frame_extracted = pkt->stream_index;
537
                        }
538
                }
539
        }
540
        else { //somebody requested a video packet, q is the video queue
541
                pkt1 = q->first_pkt;
542
                if(pkt1) {
543
#ifdef DEBUG_QUEUE
544
                        printf("  AV not 1\n");
545
#endif
546
                        pkt->size = pkt1->pkt.size;
547
                        pkt->dts = pkt1->pkt.dts;
548
                        pkt->pts = pkt1->pkt.pts;
549
                        pkt->stream_index = pkt1->pkt.stream_index;
550
                        pkt->flags = pkt1->pkt.flags;
551
                        pkt->pos = pkt1->pkt.pos;
552
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
553
                        //*pkt = pkt1->pkt;
554
                        memcpy(pkt->data, pkt1->pkt.data, pkt1->pkt.size);
555

    
556
                        //HINT SEE BEFORE q->size -= pkt1->pkt.size;
557
                        q->first_pkt = RemoveFromQueue(q, pkt1);
558

    
559
                        ret = 1;
560
                        UpdateQueueStats(q, pkt->stream_index);
561
                        //update index of last frame extracted
562
                        q->last_frame_extracted = pkt->stream_index;
563
                }
564
#ifdef DEBUG_QUEUE
565
                else {
566
                        printf("  VIDEO pk1 NULL!!!!\n");
567
                }
568
#endif
569
        }
570

    
571
        if(q->nb_packets==0 && q->queueType==AUDIO) {
572
                QueueFillingMode=1;
573
#ifdef DEBUG_QUEUE
574
                printf("QUEUE: Get FillingMode ON\n");
575
#endif
576
        }
577
#ifdef DEBUG_QUEUE
578
        printf("QUEUE: Get LastFrameExtracted = %d\n",q->last_frame_extracted);
579
        printf("QUEUE: Get Tot lost frames = %d\n",q->total_lost_frames);
580
#endif
581

    
582
        SDL_UnlockMutex(q->mutex);
583
        return ret;
584
}
585

    
586
int AudioDecodeFrame(uint8_t *audio_buf, int buf_size) {
587
        //struct timeval now;
588
        int audio_pkt_size = 0;
589
        long long Now;
590
        short int DecodeAudio=0, SkipAudio=0;
591
        //int len1, data_size;
592

    
593
        //gettimeofday(&now,NULL);
594
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
595
        Now=(long long)SDL_GetTicks();
596

    
597
        if(QueueFillingMode || QueueStopped)
598
        {
599
                //SDL_LockMutex(timing_mutex);
600
                FirstTimeAudio=1;
601
                FirstTime = 1;
602
                //SDL_UnlockMutex(timing_mutex);
603
                return -1;
604
        }
605

    
606
        if((FirstTime==1 || FirstTimeAudio==1) && audioq.size>0) {
607
                if(audioq.first_pkt->pkt.pts>0)
608
                {
609
                        //SDL_LockMutex(timing_mutex);
610
                        DeltaTime=Now-(long long)(audioq.first_pkt->pkt.pts);
611
                        FirstTimeAudio = 0;
612
                        FirstTime = 0;
613
                        //SDL_UnlockMutex(timing_mutex);
614
#ifdef DEBUG_AUDIO 
615
                         printf("AUDIO: audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTime);
616
#endif
617
                }
618
        }
619

    
620
#ifdef DEBUG_AUDIO 
621
        if(audioq.first_pkt)
622
        {
623
                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);
624
                printf("AUDIO: QueueLen=%d ",(int)audioq.nb_packets);
625
                printf("AUDIO: QueueSize=%d\n",(int)audioq.size);
626
        }
627
        else
628
                printf("AUDIO: audio_decode_frame - Empty queue\n");
629
#endif
630

    
631

    
632
        if(audioq.nb_packets>0) {
633
                if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
634
                        SkipAudio = 1;
635
                        DecodeAudio = 0;
636
                }
637
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
638
                        (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
639
                                SkipAudio = 0;
640
                                DecodeAudio = 1;
641
                }
642
        }
643
                
644
        while(SkipAudio==1 && audioq.size>0) {
645
                SkipAudio = 0;
646
#ifdef DEBUG_AUDIO
647
                 printf("AUDIO: skipaudio: queue size=%d\n",audioq.size);
648
#endif
649
                if(PacketQueueGet(&audioq,&AudioPkt,1) < 0) {
650
                        return -1;
651
                }
652
                if(audioq.first_pkt)
653
                {
654
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
655
                                SkipAudio = 1;
656
                                DecodeAudio = 0;
657
                        }
658
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
659
                                (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
660
                                        SkipAudio = 0;
661
                                        DecodeAudio = 1;
662
                        }
663
                }
664
        }
665
        if(DecodeAudio==1) {
666
                if(PacketQueueGet(&audioq,&AudioPkt,1) < 0) {
667
                        return -1;
668
                }
669
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
670
                audio_pkt_size = AudioPkt.size;
671
#ifdef DEBUG_AUDIO
672
                 printf("AUDIO: Decode audio\n");
673
#endif
674
        }
675

    
676
        return audio_pkt_size;
677
}
678

    
679
int VideoCallback(void *valthread)
680
{
681
        //AVPacket pktvideo;
682
        AVCodecContext  *pCodecCtx;
683
        AVCodec         *pCodec;
684
        AVFrame         *pFrame;
685
        AVPacket        packet;
686
        int frameFinished;
687
        int countexit;
688
        AVPicture pict;
689
        //FILE *frecon;
690
        SDL_Event event;
691
        long long Now;
692
        short int SkipVideo, DecodeVideo;
693

    
694
        //double frame_rate = 0.0,time_between_frames=0.0;
695
        //struct timeval now;
696

    
697
        //int wait_for_sync = 1;
698
        ThreadVal *tval;
699
        tval = (ThreadVal *)valthread;
700

    
701
        //frame_rate = tval->framerate;
702
        //time_between_frames = 1.e6 / frame_rate;
703
        //gettimeofday(&time_now,0);
704

    
705
        //frecon = fopen("recondechunk.mpg","wb");
706

    
707
        pCodecCtx=avcodec_alloc_context();
708
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
709
#ifdef H264_VIDEO_ENCODER
710
        pCodecCtx->codec_id  = CODEC_ID_H264;
711
        pCodecCtx->me_range = 16;
712
        pCodecCtx->max_qdiff = 4;
713
        pCodecCtx->qmin = 10;
714
        pCodecCtx->qmax = 51;
715
        pCodecCtx->qcompress = 0.6;
716
#else
717
        pCodecCtx->codec_id  = CODEC_ID_MPEG4;
718
#endif
719
        //pCodecCtx->bit_rate = 400000;
720
        // resolution must be a multiple of two
721
        pCodecCtx->width = tval->width;//176;//352;
722
        pCodecCtx->height = tval->height;//144;//288;
723
        
724
        // frames per second
725
        //pCodecCtx->time_base = (AVRational){1,25};
726
        //pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
727
        //pCodecCtx->max_b_frames=1;
728
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
729
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
730

    
731
        if(pCodec==NULL) {
732
                fprintf(stderr, "Unsupported codec!\n");
733
                return -1; // Codec not found
734
        }
735
        if(avcodec_open(pCodecCtx, pCodec) < 0) {
736
                fprintf(stderr, "could not open codec\n");
737
                return -1; // Could not open codec
738
        }
739
        pFrame=avcodec_alloc_frame();
740
        if(pFrame==NULL) {
741
                printf("Memory error!!!\n");
742
                return -1;
743
        }
744
        
745
#ifdef DEBUG_VIDEO
746
         printf("VIDEO: video_callback entering main cycle\n");
747
#endif
748
        while(AVPlaying && !quit) {
749
                if(QueueFillingMode || QueueStopped)
750
                {
751
                        //SDL_LockMutex(timing_mutex);
752
                        FirstTime = 1;
753
                        //SDL_UnlockMutex(timing_mutex);
754
                        usleep(5000);
755
                        continue;
756
                }
757

    
758
                DecodeVideo = 0;
759
                SkipVideo = 0;
760
                Now=(long long)SDL_GetTicks();
761
                if(FirstTime==1 && videoq.size>0) {
762
                        if(videoq.first_pkt->pkt.pts>0)
763
                        {
764
                                //SDL_LockMutex(timing_mutex);
765
                                DeltaTime=Now-(long long)videoq.first_pkt->pkt.pts;
766
                                FirstTime = 0;
767
                                //SDL_UnlockMutex(timing_mutex);
768
                        }
769
#ifdef DEBUG_VIDEO 
770
                         printf("VIDEO: VideoCallback - DeltaTimeAudio=%lld\n",DeltaTime);
771
#endif
772
                }
773

    
774
#ifdef DEBUG_VIDEO 
775
                if(videoq.first_pkt)
776
                {
777
                        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);
778
                        printf("VIDEO: Index=%d ", (int)videoq.first_pkt->pkt.stream_index);
779
                        printf("VIDEO: QueueLen=%d ", (int)videoq.nb_packets);
780
                        printf("VIDEO: QueueSize=%d\n", (int)videoq.size);
781
                }
782
                else
783
                        printf("VIDEO: VideoCallback - Empty queue\n");
784
#endif
785

    
786
                if(videoq.nb_packets>0) {
787
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)<Now-(long long)MAX_TOLLERANCE) {
788
                                SkipVideo = 1;
789
                                DecodeVideo = 0;
790
                        }
791
                        else 
792
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)>=Now-(long long)MAX_TOLLERANCE &&
793
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTime)<=Now+(long long)MAX_TOLLERANCE) {
794
                                        SkipVideo = 0;
795
                                        DecodeVideo = 1;
796
                                }
797
                }
798
#ifdef DEBUG_VIDEO
799
                printf("VIDEO: skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
800
#endif
801

    
802
                while(SkipVideo==1 && videoq.size>0) {
803
                        SkipVideo = 0;
804
#ifdef DEBUG_VIDEO 
805
                         printf("VIDEO: Skip Video\n");
806
#endif
807
                        if(PacketQueueGet(&videoq,&VideoPkt,0) < 0) {
808
                                break;
809
                        }
810
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
811
                        if(videoq.first_pkt)
812
                        {
813
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
814
                                        SkipVideo = 1;
815
                                        DecodeVideo = 0;
816
                                }
817
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
818
                                                                (long long)videoq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
819
                                        SkipVideo = 0;
820
                                        DecodeVideo = 1;
821
                                }
822
                        }
823
                }
824
                
825
                if(DecodeVideo==1) {
826
                        if(PacketQueueGet(&videoq,&VideoPkt,0) > 0) {
827

    
828
#ifdef DEBUG_VIDEO
829
                                printf("VIDEO: Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
830
#endif
831

    
832
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
833

    
834
                                if(frameFinished) { // it must be true all the time else error
835
#ifdef DEBUG_VIDEO
836
                                        printf("VIDEO: FrameFinished\n");
837
#endif
838
                                        if(SaveYUV)
839
                                                SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height);
840
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
841

    
842
                                        if(SilentMode)
843
                                                continue;
844

    
845
                                        // Lock SDL_yuv_overlay
846
                                        if(SDL_MUSTLOCK(MainScreen)) {
847
                                                if(SDL_LockSurface(MainScreen) < 0) {
848
                                                        continue;
849
                                                }
850
                                        }
851

    
852
                                        if(SDL_LockYUVOverlay(YUVOverlay) < 0) {
853
                                                if(SDL_MUSTLOCK(MainScreen)) {
854
                                                        SDL_UnlockSurface(MainScreen);
855
                                                }
856
                                                continue;
857
                                        }
858
                                        
859
                                        pict.data[0] = YUVOverlay->pixels[0];
860
                                        pict.data[1] = YUVOverlay->pixels[2];
861
                                        pict.data[2] = YUVOverlay->pixels[1];
862

    
863
                                        pict.linesize[0] = YUVOverlay->pitches[0];
864
                                        pict.linesize[1] = YUVOverlay->pitches[2];
865
                                        pict.linesize[2] = YUVOverlay->pitches[1];
866

    
867
                                        if(img_convert_ctx == NULL) {
868
                                                img_convert_ctx = sws_getContext(tval->width, tval->height, PIX_FMT_YUV420P, InitRect->w, InitRect->h, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
869
                                                if(img_convert_ctx == NULL) {
870
                                                        fprintf(stderr, "Cannot initialize the conversion context!\n");
871
                                                        exit(1);
872
                                                }
873
                                        }
874
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
875
                                        sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, tval->height, pict.data, pict.linesize);
876
                                        SDL_UnlockYUVOverlay(YUVOverlay);
877
                                        // Show, baby, show!
878
                                        SDL_LockMutex(OverlayMutex);
879
                                        SDL_DisplayYUVOverlay(YUVOverlay, &OverlayRect);
880
                                        SDL_UnlockMutex(OverlayMutex);
881

    
882
                                        //redisplay logo
883
                                        /**SDL_BlitSurface(image, NULL, MainScreen, &dest);*/
884
                                        /* Update the screen area just changed */
885
                                        /**SDL_UpdateRects(MainScreen, 1, &dest);*/
886

    
887
                                        if(SDL_MUSTLOCK(MainScreen)) {
888
                                                SDL_UnlockSurface(MainScreen);
889
                                        }
890
                                } //if FrameFinished
891
                        } // if packet_queue_get
892
                } //if DecodeVideo=1
893

    
894
                usleep(5000);
895
        }
896
        
897
        av_free(pCodecCtx);
898
        av_free(pFrame);
899
        //fclose(frecon);
900
#ifdef DEBUG_VIDEO
901
         printf("VIDEO: video callback end\n");
902
#endif
903
        return 0;
904
}
905

    
906
void AudioCallback(void *userdata, Uint8 *stream, int len)
907
{
908
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
909
        int audio_size;
910

    
911
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
912

    
913
        audio_size = AudioDecodeFrame(audio_buf, sizeof(audio_buf));
914
        if(audio_size != len) {
915
                memset(stream, 0, len);
916
        } else {
917
                memcpy(stream, (uint8_t *)audio_buf, len);
918
        }
919
}
920

    
921
void SaveFrame(AVFrame *pFrame, int width, int height)
922
{
923
        FILE *pFile;
924
        int  y;
925
  
926
         // Open file
927
        pFile=fopen(YUVFileName, "ab");
928
        if(pFile==NULL)
929
                return;
930
  
931
        // Write header
932
        //fprintf(pFile, "P5\n%d %d\n255\n", width, height);
933
  
934
        // Write Y data
935
        for(y=0; y<height; y++)
936
                  fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
937
        // Write U data
938
        for(y=0; y<height/2; y++)
939
                  fwrite(pFrame->data[1]+y*pFrame->linesize[1], 1, width/2, pFile);
940
        // Write V data
941
        for(y=0; y<height/2; y++)
942
                  fwrite(pFrame->data[2]+y*pFrame->linesize[2], 1, width/2, pFile);
943
  
944
        // Close file
945
        fclose(pFile);
946
}
947

    
948
int ChunkerPlayerCore_IsRunning()
949
{
950
        return AVPlaying;
951
}
952

    
953
void ChunkerPlayerCore_Play()
954
{
955
        if(AVPlaying) return;
956
        
957
        AVPlaying = 1;
958
        SDL_PauseAudio(0);
959
        video_thread = SDL_CreateThread(VideoCallback, &VideoCallbackThreadParams);
960
}
961

    
962
void ChunkerPlayerCore_Stop()
963
{
964
        if(!AVPlaying) return;
965
        
966
        AVPlaying = 0;
967
        
968
        // Stop audio&video playback
969
        SDL_WaitThread(video_thread, NULL);
970
        SDL_PauseAudio(1);
971
        SDL_CloseAudio();
972
        
973
        if(YUVOverlay != NULL)
974
        {
975
                SDL_FreeYUVOverlay(YUVOverlay);
976
                YUVOverlay = NULL;
977
        }
978
        
979
        PacketQueueReset(&audioq, AUDIO);
980
        PacketQueueReset(&videoq, VIDEO);
981
        
982
        av_free(aCodecCtx);
983
        free(AudioPkt.data);
984
        free(VideoPkt.data);
985
        free(outbuf_audio);
986
        free(InitRect);
987
        
988
        return 0;
989
}
990

    
991
int ChunkerPlayerCore_VideoEnded()
992
{
993
        return (audioq.nb_packets==0 && audioq.last_frame_extracted>0);
994
}
995

    
996
void ChunkerPlayerCore_ResetAVQueues()
997
{
998
#ifdef DEBUG_QUEUE
999
        printf("QUEUE: MAIN SHOULD RESET\n");
1000
#endif
1001
        PacketQueueReset(&audioq, AUDIO);
1002
        PacketQueueReset(&videoq, VIDEO);
1003
}
1004

    
1005
int ChunkerPlayerCore_EnqueueBlocks(const uint8_t *block, const int block_size)
1006
{
1007
        Chunk *gchunk = NULL;
1008
        ExternalChunk *echunk = NULL;
1009
        int decoded_size = -1;
1010
        uint8_t *tempdata, *buffer;
1011
        int i, j;
1012
        Frame *frame = NULL;
1013
        AVPacket packet, packetaudio;
1014

    
1015
        uint16_t *audio_bufQ = NULL;
1016

    
1017
        //the frame.h gets encoded into 5 slots of 32bits (3 ints plus 2 more for the timeval struct
1018
        static int sizeFrameHeader = 5*sizeof(int32_t);
1019
        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;
1020

    
1021
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1022
        if(!audio_bufQ) {
1023
                printf("Memory error in audio_bufQ!\n");
1024
                return PLAYER_FAIL_RETURN;
1025
        }
1026

    
1027
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1028
        if(!gchunk) {
1029
                printf("Memory error in gchunk!\n");
1030
                av_free(audio_bufQ);
1031
                return PLAYER_FAIL_RETURN;
1032
        }
1033

    
1034
        decoded_size = decodeChunk(gchunk, block, block_size);
1035
#ifdef DEBUG_CHUNKER
1036
        printf("CHUNKER: enqueueBlock: decoded_size %d target size %d\n", decoded_size, GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size);
1037
#endif
1038
  if(decoded_size < 0 || decoded_size != GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size) {
1039
                //HINT here i should differentiate between various return values of the decode
1040
                //in order to free what has been allocated there
1041
                printf("chunk probably corrupted!\n");
1042
                av_free(audio_bufQ);
1043
                free(gchunk);
1044
                return PLAYER_FAIL_RETURN;
1045
        }
1046

    
1047
        echunk = grapesChunkToExternalChunk(gchunk);
1048
        if(echunk == NULL) {
1049
                printf("Memory error in echunk!\n");
1050
                free(gchunk->attributes);
1051
                free(gchunk->data);
1052
                free(gchunk);
1053
                return PLAYER_FAIL_RETURN;
1054
        }
1055
        free(gchunk->attributes);
1056
        free(gchunk);
1057

    
1058
        frame = (Frame *)malloc(sizeof(Frame));
1059
        if(!frame) {
1060
                printf("Memory error in Frame!\n");
1061
                if(gchunk->attributes)
1062
                        free(gchunk->attributes);
1063
                if(echunk->data)
1064
                        free(echunk->data);
1065
                if(echunk)
1066
                        free(echunk);
1067
                av_free(audio_bufQ);
1068
                return PLAYER_FAIL_RETURN;
1069
        }
1070

    
1071
        tempdata = echunk->data; //let it point to first frame of payload
1072
        j=echunk->payload_len;
1073
        while(j>0 && !quit) {
1074
                frame->number = bit32_encoded_pull(tempdata);
1075
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1076
                frame->timestamp.tv_sec = bit32_encoded_pull(tempdata);
1077
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1078
                frame->timestamp.tv_usec = bit32_encoded_pull(tempdata);
1079
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1080
                frame->size = bit32_encoded_pull(tempdata);
1081
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1082
                frame->type = bit32_encoded_pull(tempdata);
1083
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1084

    
1085
                buffer = tempdata; // here coded frame information
1086
                tempdata += frame->size; //let it point to the next frame
1087

    
1088
                if(frame->type < 5) { // video frame
1089
                        av_init_packet(&packet);
1090
                        packet.data = buffer;//video_bufQ;
1091
                        packet.size = frame->size;
1092
                        packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1093
                        packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1094
                        packet.stream_index = frame->number; // use of stream_index for number frame
1095
                        //packet.duration = frame->timestamp.tv_sec;
1096
                        if(packet.size > 0)
1097
                                ChunkerPlayerCore_PacketQueuePut(&videoq, &packet); //the _put makes a copy of the packet
1098

    
1099
#ifdef DEBUG_SOURCE
1100
                        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);
1101
#endif
1102
                }
1103
                else if(frame->type == 5) { // audio frame
1104
                        av_init_packet(&packetaudio);
1105
                        packetaudio.data = buffer;
1106
                        packetaudio.size = frame->size;
1107
                        packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1108
                        packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1109
                        //packetaudio.duration = frame->timestamp.tv_sec;
1110
                        packetaudio.stream_index = frame->number; // use of stream_index for number frame
1111
                        packetaudio.flags = 1;
1112
                        packetaudio.pos = -1;
1113

    
1114
                        //instead of -1, in order to signal it is not decoded yet
1115
                        packetaudio.convergence_duration = 0;
1116

    
1117
                        // insert the audio frame into the queue
1118
                        if(packetaudio.size > 0)
1119
                                ChunkerPlayerCore_PacketQueuePut(&audioq, &packetaudio);//makes a copy of the packet so i can free here
1120

    
1121
#ifdef DEBUG_SOURCE
1122
                        printf("SOURCE: Insert audio in queue pts=%lld sindex:%d\n", packetaudio.pts, packetaudio.stream_index);
1123
#endif
1124
                }
1125
                else {
1126
                        printf("SOURCE: Unknown frame type %d. Size %d\n", frame->type, frame->size);
1127
                }
1128
                if(frame->size > 0)
1129
                        j = j - sizeFrameHeader - frame->size;
1130
                else {
1131
                        printf("SOURCE: Corrupt frames (size %d) in chunk. Skipping it...\n", frame->size);
1132
                        j = -1;
1133
                }
1134
        }
1135
        //chunk ingestion terminated!
1136
        if(echunk->data)
1137
                free(echunk->data);
1138
        if(echunk)
1139
                free(echunk);
1140
        if(frame)
1141
                free(frame);
1142
        if(audio_bufQ)
1143
                av_free(audio_bufQ);
1144
}
1145

    
1146
void ChunkerPlayerCore_SetupOverlay(int width, int height)
1147
{
1148
        SDL_LockMutex(OverlayMutex);
1149
        if(YUVOverlay != NULL)
1150
        {
1151
                SDL_FreeYUVOverlay(YUVOverlay);
1152
                YUVOverlay = NULL;
1153
        }
1154
        
1155
        // create video overlay for display of video frames
1156
        // printf("SDL_CreateYUVOverlay(%d, %d, SDL_YV12_OVERLAY, MainScreen)\n", width, height);
1157
        YUVOverlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, MainScreen);
1158
        // YUVOverlay = SDL_CreateYUVOverlay(OverlayRect.w, OverlayRect.h, SDL_YV12_OVERLAY, MainScreen);
1159
        if ( YUVOverlay == NULL )
1160
        {
1161
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
1162
                exit(1);
1163
        }
1164

    
1165
        if ( YUVOverlay->hw_overlay )
1166
                fprintf(stderr,"SDL: Using hardware overlay.\n");
1167
        // OverlayRect.x = (screen_w - width) / 2;
1168
        
1169
        SDL_DisplayYUVOverlay(YUVOverlay, &OverlayRect);
1170
        
1171
        SDL_UnlockMutex(OverlayMutex);
1172
}