Statistics
| Branch: | Revision:

chunker-player / chunker_player / player_core.c @ 31e4e8ba

History | View | Annotate | Download (34.6 KB)

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

    
7
void SaveFrame(AVFrame *pFrame, int width, int height);
8
int VideoCallback(void *valthread);
9
void AudioCallback(void *userdata, Uint8 *stream, int len);
10
void UpdateQueueStats(PacketQueue *q, int packet_index);
11
void UpdateLossTraces(int type, int first_lost, int n_lost);
12

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

    
36
void PacketQueueReset(PacketQueue *q, short int Type)
37
{
38
        AVPacketList *tmp,*tmp1;
39
#ifdef DEBUG_QUEUE
40
        printf("QUEUE: RESET BEGIN: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
41
#endif
42
        SDL_LockMutex(q->mutex);
43

    
44
        tmp = q->first_pkt;
45
        while(tmp) {
46
                tmp1 = tmp;
47
                tmp = tmp->next;
48
                av_free_packet(&(tmp1->pkt));
49
                av_free(tmp1);
50
#ifdef DEBUG_QUEUE
51
                printf("F ");
52
#endif
53
        }
54
#ifdef DEBUG_QUEUE
55
        printf("\n");
56
#endif
57

    
58
        QueueFillingMode=1;
59
        q->last_frame_extracted = -1;
60
        
61
        // on queue reset do not reset loss count
62
        // (loss count reset is done on queue init, ie channel switch)
63
        // q->total_lost_frames = 0;
64
        q->density=0.0;
65
        q->first_pkt= NULL;
66
        //q->last_pkt = NULL;
67
        q->nb_packets = 0;
68
        q->size = 0;
69
        FirstTime = 1;
70
        FirstTimeAudio = 1;
71
#ifdef DEBUG_QUEUE
72
        printf("QUEUE: RESET END: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
73
#endif
74
        SDL_UnlockMutex(q->mutex);
75
}
76

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

    
98
        if(!pkt1) {
99
                av_free_packet(pkt);
100
                return -1;
101
        }
102
        pkt1->pkt = *pkt;
103
        pkt1->next = NULL;
104

    
105
        SDL_LockMutex(q->mutex);
106

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

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

    
172
        SDL_UnlockMutex(q->mutex);
173
        return 0;
174
}
175

    
176
int ChunkerPlayerCore_InitCodecs(int width, int height, int sample_rate, short int audio_channels)
177
{
178
        // some initializations
179
        QueueStopped = 0;
180
        AudioQueueOffset=0;
181
        AVPlaying = 0;
182
        GotSigInt = 0;
183
        FirstTimeAudio=1;
184
        FirstTime = 1;
185
        deltaAudioQError=0;
186
        InitRect = NULL;
187
        img_convert_ctx = NULL;
188
        
189
        SDL_AudioSpec wanted_spec;
190
        AVCodec         *aCodec;
191
        
192
        memset(&VideoCallbackThreadParams, 0, sizeof(ThreadVal));
193
        
194
        VideoCallbackThreadParams.width = width;
195
        VideoCallbackThreadParams.height = height;
196

    
197
        // Register all formats and codecs
198
        av_register_all();
199

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

    
236
#ifdef DEBUG_AUDIO
237
        printf("freq:%d\n",AudioSpecification.freq);
238
        printf("format:%d\n",AudioSpecification.format);
239
        printf("channels:%d\n",AudioSpecification.channels);
240
        printf("silence:%d\n",AudioSpecification.silence);
241
        printf("samples:%d\n",AudioSpecification.samples);
242
        printf("size:%d\n",AudioSpecification.size);
243
        printf("deltaAudioQ: %f\n",deltaAudioQ);
244
#endif
245

    
246
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
247

    
248
        //initialize the audio and the video queues
249
        PacketQueueInit(&audioq, AUDIO);
250
        PacketQueueInit(&videoq, VIDEO);
251
        
252
        // Init audio and video buffers
253
        av_init_packet(&AudioPkt);
254
        av_init_packet(&VideoPkt);
255
        printf("AVCODEC_MAX_AUDIO_FRAME_SIZE=%d\n", AVCODEC_MAX_AUDIO_FRAME_SIZE);
256
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
257
        if(!AudioPkt.data) return 1;
258
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
259
        if(!VideoPkt.data) return 1;
260
        
261
        InitRect = (SDL_Rect*) malloc(sizeof(SDL_Rect));
262
        if(!InitRect)
263
        {
264
                printf("Memory error!!!\n");
265
                return -1;
266
        }
267
        InitRect->x = OverlayRect.x;
268
        InitRect->y = OverlayRect.y;
269
        InitRect->w = OverlayRect.w;
270
        InitRect->h = OverlayRect.h;
271
        
272
        char audio_stats[255], video_stats[255];
273
        sprintf(audio_stats, "waiting for incoming audio packets...");
274
        sprintf(video_stats, "waiting for incoming video packets...");
275
        ChunkerPlayerGUI_SetStatsText(audio_stats, video_stats);
276
        
277
        return 0;
278
}
279

    
280
int DecodeEnqueuedAudio(AVPacket *pkt, PacketQueue *q)
281
{
282
        uint16_t *audio_bufQ = NULL;
283
        int16_t *dataQ = NULL;
284
        int data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
285
        int lenQ;
286
        int ret = 0;
287

    
288
        //set the flag to decoded anyway        
289
        pkt->convergence_duration = -1;
290

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

    
333
/**
334
 * removes a packet from the list and returns the next
335
 * */
336
AVPacketList *RemoveFromQueue(PacketQueue *q, AVPacketList *p)
337
{
338
        AVPacketList *retpk = p->next;
339
        q->nb_packets--;
340
        //adjust size here and not in the various cases of the dequeue
341
        q->size -= p->pkt.size;
342
        if(&p->pkt)
343
                av_free_packet(&p->pkt);
344
        if(p)
345
                av_free(p);
346
        return retpk;
347
}
348

    
349
AVPacketList *SeekAndDecodePacketStartingFrom(AVPacketList *p, PacketQueue *q)
350
{
351
        while(p) {
352
                        //check if audio packet has been already decoded
353
                        if(p->pkt.convergence_duration == 0) {
354
                                //not decoded yet, try to decode it
355
                                if( !DecodeEnqueuedAudio(&(p->pkt), q) ) {
356
                                        //it was not possible to decode this packet, return next one
357
                                        p = RemoveFromQueue(q, p);
358
                                }
359
                                else
360
                                        return p;
361
                        }
362
                        else
363
                                return p;
364
        }
365
        return NULL;
366
}
367

    
368
void UpdateQueueStats(PacketQueue *q, int packet_index)
369
{
370
        static int N = 50;
371
        static int last_print = 0;
372
        
373
        if(q == NULL)
374
                return;
375
        if(q->first_pkt == NULL)
376
                return;
377
        if(q->last_pkt == NULL)
378
                return;
379
        
380
        if(q->last_pkt->pkt.stream_index > q->first_pkt->pkt.stream_index)
381
        {
382
                q->density = (double)q->nb_packets / (double)(q->last_pkt->pkt.stream_index - q->first_pkt->pkt.stream_index) * 100.0;
383
        }
384
        
385
#ifdef DEBUG_STATS
386
        if(q->queueType == AUDIO)
387
                printf("STATS: AUDIO QUEUE DENSITY percentage %f\n", q->density);
388
        if(q->queueType == VIDEO)
389
                printf("STATS: VIDEO QUEUE DENSITY percentage %f\n", q->density);
390
#endif
391
        
392
        if(!last_print)
393
                last_print = time(NULL);
394
                
395
        int now = time(NULL);
396
        int lost_frames = 0;
397
        
398
        if(packet_index != -1)
399
        {
400
                double percentage = 0.0;        
401
                //compute lost frame statistics
402
                if(q->last_frame_extracted > 0 && packet_index > q->last_frame_extracted)
403
                {
404
                        lost_frames = packet_index - q->last_frame_extracted - 1;
405
                        q->total_lost_frames += lost_frames ;
406
                        percentage = (double)q->total_lost_frames / (double)q->last_frame_extracted * 100.0;
407
                        
408
                        q->instant_lost_frames += lost_frames;
409
                        
410
                        //save a trace of lost frames to file
411
                        //we have lost "lost_frames" frames starting from the last extracted (excluded of course)
412
                        UpdateLossTraces(q->queueType, q->last_frame_extracted+1, lost_frames);
413
                        
414
                        /**q->loss_history[q->history_index] = lost_frames;
415
                        q->history_index = (q->history_index+1)%N;
416
                        
417
                        int i;
418
                        q->instant_lost_frames = 0;
419
                        for(i=0; i<N; i++)
420
                                q->instant_lost_frames += q->loss_history[i];*/
421
                        
422
#ifdef DEBUG_STATS
423
                        if(q->queueType == AUDIO)
424
                                printf("STATS: AUDIO FRAMES LOST: instant %d, total %d, total percentage %f\n", q->instant_lost_frames, q->total_lost_frames, percentage);
425
                        else if(q->queueType == VIDEO)
426
                                printf("STATS: VIDEO FRAMES LOST: instant %d, total %d, total percentage %f\n", q->instant_lost_frames, q->total_lost_frames, percentage);
427
#endif
428
                }
429
        }
430
        
431
        if((now-last_print) >= 1)
432
        {
433
                char stats[255];
434
                if(q->queueType == AUDIO)
435
                {
436
                        sprintf(stats, "[AUDIO] queue density: %d --- lost_frames/sec: %d --- total_lost_frames: %d", (int)q->density, q->instant_lost_frames, q->total_lost_frames);
437
                        ChunkerPlayerGUI_SetStatsText(stats, NULL);
438
                }
439
                else if(q->queueType == VIDEO)
440
                {
441
                        sprintf(stats, "[VIDEO] queue density: %d --- lost_frames/sec: %d --- total_lost_frames: %d", (int)q->density, q->instant_lost_frames, q->total_lost_frames);
442
                        ChunkerPlayerGUI_SetStatsText(NULL, stats);
443
                }
444
                
445
                last_print = now;
446
                q->instant_lost_frames = 0;
447
        }
448
}
449

    
450
void UpdateLossTraces(int type, int first_lost, int n_lost)
451
{
452
        FILE *lossFile;
453
        int i;
454

    
455
        // Open loss traces file
456
        char filename[255];
457
        if(type == AUDIO)
458
                sprintf(filename, "audio_%s", LossTracesFilename);
459
        else
460
                sprintf(filename, "video_%s", LossTracesFilename);
461

    
462
        lossFile=fopen(filename, "a");
463
        if(lossFile==NULL) {
464
                printf("STATS: UNABLE TO OPEN Loss FILE: %s\n", filename);
465
                return;
466
        }
467

    
468
        for(i=0; i<n_lost; i++) {
469
                fprintf(lossFile, "%d\n", first_lost+i);
470
        }
471

    
472
        fclose(lossFile);
473
}
474

    
475
int PacketQueueGet(PacketQueue *q, AVPacket *pkt, short int av) {
476
        //AVPacket tmp;
477
        AVPacketList *pkt1 = NULL;
478
        int ret=-1;
479
        int SizeToCopy=0;
480

    
481
        SDL_LockMutex(q->mutex);
482

    
483
#ifdef DEBUG_QUEUE
484
        printf("QUEUE: Get NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
485
#endif
486

    
487
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
488
        {
489
                SDL_UnlockMutex(q->mutex);
490
                return -1;
491
        }
492

    
493
        if(av==1) { //somebody requested an audio packet, q is the audio queue
494
                //try to dequeue the first packet of the audio queue
495
                pkt1 = SeekAndDecodePacketStartingFrom(q->first_pkt, q);
496
                if(pkt1) { //yes we have them!
497
                        if(pkt1->pkt.size-AudioQueueOffset > dimAudioQ) {
498
                                //one packet if enough to give us the requested number of bytes by the audio_callback
499
#ifdef DEBUG_QUEUE
500
                                printf("  AV=1 and Extract from the same packet\n");
501
#endif
502
                                pkt->size = dimAudioQ;
503
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
504
                                pkt->dts = pkt1->pkt.dts;
505
                                pkt->pts = pkt1->pkt.pts;
506
                                pkt->stream_index = pkt1->pkt.stream_index;//1;
507
                                pkt->flags = 1;
508
                                pkt->pos = -1;
509
                                pkt->convergence_duration = -1;
510
#ifdef DEBUG_QUEUE
511
                                printf("   Adjust timestamps Old = %lld New = %lld\n", pkt1->pkt.dts, (int64_t)(pkt1->pkt.dts + deltaAudioQ + deltaAudioQError));
512
#endif
513
                                int64_t Olddts=pkt1->pkt.dts;
514
                                pkt1->pkt.dts += deltaAudioQ + deltaAudioQError;
515
                                pkt1->pkt.pts += deltaAudioQ + deltaAudioQError;
516
                                deltaAudioQError=(float)Olddts + deltaAudioQ + deltaAudioQError - (float)pkt1->pkt.dts;
517
                                AudioQueueOffset += dimAudioQ;
518
#ifdef DEBUG_QUEUE
519
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
520
#endif
521
                                //update overall state of queue
522
                                //size is diminished because we played some audio samples
523
                                //but packet is not removed since a portion has still to be played
524
                                //HINT ERRATA we had a size mismatch since size grows with the
525
                                //number of compressed bytes, and diminishes here with the number
526
                                //of raw uncompressed bytes, hence we update size during the
527
                                //real removes and not here anymore
528
                                //q->size -= dimAudioQ;
529
                                UpdateQueueStats(q, pkt->stream_index);
530
                                //update index of last frame extracted
531
                                q->last_frame_extracted = pkt->stream_index;
532
#ifdef DEBUG_AUDIO_BUFFER
533
                                printf("1: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
534
#endif
535
                                ret = 1; //OK
536
                        }
537
                        else {
538
                                //we need bytes from two consecutive packets to satisfy the audio_callback
539
#ifdef DEBUG_QUEUE
540
                                printf("  AV = 1 and Extract from 2 packets\n");
541
#endif
542
                                //check for a valid next packet since we will finish the current packet
543
                                //and also take some bytes from the next one
544
                                pkt1->next = SeekAndDecodePacketStartingFrom(pkt1->next, q);
545
                                if(pkt1->next) {
546
#ifdef DEBUG_QUEUE
547
                                        printf("   we have a next...\n");
548
#endif
549
                                        pkt->size = dimAudioQ;
550
                                        pkt->dts = pkt1->pkt.dts;
551
                                        pkt->pts = pkt1->pkt.pts;
552
                                        pkt->stream_index = pkt1->pkt.stream_index;//1;
553
                                        pkt->flags = 1;
554
                                        pkt->pos = -1;
555
                                        pkt->convergence_duration = -1;
556
                                        {
557
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
558
#ifdef DEBUG_QUEUE
559
                                                printf("      SizeToCopy=%d\n",SizeToCopy);
560
#endif
561
                                                memcpy(pkt->data, pkt1->pkt.data+AudioQueueOffset, SizeToCopy);
562
                                                memcpy(pkt->data+SizeToCopy, pkt1->next->pkt.data, (dimAudioQ-SizeToCopy)*sizeof(uint8_t));
563
                                        }
564
#ifdef DEBUG_AUDIO_BUFFER
565
                                        printf("2: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
566
#endif
567
                                }
568
#ifdef DEBUG_AUDIO_BUFFER
569
                                else {
570
                                        printf("2: NONEXT\n");
571
                                }
572
#endif
573
                                //HINT SEE before q->size -= SizeToCopy;
574
                                q->first_pkt = RemoveFromQueue(q, pkt1);
575

    
576
                                // Adjust timestamps
577
                                pkt1 = q->first_pkt;
578
                                if(pkt1) {
579
                                        int Offset=(dimAudioQ-SizeToCopy)*1000/(AudioSpecification.freq*2*AudioSpecification.channels);
580
                                        int64_t LastDts=pkt1->pkt.dts;
581
                                        pkt1->pkt.dts += Offset + deltaAudioQError;
582
                                        pkt1->pkt.pts += Offset + deltaAudioQError;
583
                                        deltaAudioQError = (float)LastDts + (float)Offset + deltaAudioQError - (float)pkt1->pkt.dts;
584
#ifdef DEBUG_QUEUE
585
                                        printf("   Adjust timestamps Old = %lld New = %lld\n", LastDts, pkt1->pkt.dts);
586
#endif
587
                                        AudioQueueOffset = dimAudioQ - SizeToCopy;
588
                                        //SEE BEFORE HINT q->size -= AudioQueueOffset;
589
                                        ret = 1;
590
                                        UpdateQueueStats(q, pkt->stream_index);
591
                                }
592
                                else {
593
                                        AudioQueueOffset=0;
594
                                }
595
#ifdef DEBUG_QUEUE
596
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
597
#endif
598
                                //update index of last frame extracted
599
                                q->last_frame_extracted = pkt->stream_index;
600
                        }
601
                }
602
        }
603
        else { //somebody requested a video packet, q is the video queue
604
                pkt1 = q->first_pkt;
605
                if(pkt1) {
606
#ifdef DEBUG_QUEUE
607
                        printf("  AV not 1\n");
608
#endif
609
                        pkt->size = pkt1->pkt.size;
610
                        pkt->dts = pkt1->pkt.dts;
611
                        pkt->pts = pkt1->pkt.pts;
612
                        pkt->stream_index = pkt1->pkt.stream_index;
613
                        pkt->flags = pkt1->pkt.flags;
614
                        pkt->pos = pkt1->pkt.pos;
615
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
616
                        //*pkt = pkt1->pkt;
617
                        memcpy(pkt->data, pkt1->pkt.data, pkt1->pkt.size);
618

    
619
                        //HINT SEE BEFORE q->size -= pkt1->pkt.size;
620
                        q->first_pkt = RemoveFromQueue(q, pkt1);
621

    
622
                        ret = 1;
623
                        UpdateQueueStats(q, pkt->stream_index);
624
                        //update index of last frame extracted
625
                        q->last_frame_extracted = pkt->stream_index;
626
                }
627
#ifdef DEBUG_QUEUE
628
                else {
629
                        printf("  VIDEO pk1 NULL!!!!\n");
630
                }
631
#endif
632
        }
633

    
634
        if(q->nb_packets==0 && q->queueType==AUDIO) {
635
                QueueFillingMode=1;
636
#ifdef DEBUG_QUEUE
637
                printf("QUEUE: Get FillingMode ON\n");
638
#endif
639
        }
640
#ifdef DEBUG_QUEUE
641
        printf("QUEUE: Get LastFrameExtracted = %d\n",q->last_frame_extracted);
642
        printf("QUEUE: Get Tot lost frames = %d\n",q->total_lost_frames);
643
#endif
644

    
645
        SDL_UnlockMutex(q->mutex);
646
        return ret;
647
}
648

    
649
int AudioDecodeFrame(uint8_t *audio_buf, int buf_size) {
650
        //struct timeval now;
651
        int audio_pkt_size = 0;
652
        long long Now;
653
        short int DecodeAudio=0, SkipAudio=0;
654
        //int len1, data_size;
655

    
656
        //gettimeofday(&now,NULL);
657
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
658
        Now=(long long)SDL_GetTicks();
659

    
660
        if(QueueFillingMode || QueueStopped)
661
        {
662
                //SDL_LockMutex(timing_mutex);
663
                FirstTimeAudio=1;
664
                FirstTime = 1;
665
                //SDL_UnlockMutex(timing_mutex);
666
                return -1;
667
        }
668

    
669
        if((FirstTime==1 || FirstTimeAudio==1) && audioq.size>0) {
670
                if(audioq.first_pkt->pkt.pts>0)
671
                {
672
                        //SDL_LockMutex(timing_mutex);
673
                        DeltaTime=Now-(long long)(audioq.first_pkt->pkt.pts);
674
                        FirstTimeAudio = 0;
675
                        FirstTime = 0;
676
                        //SDL_UnlockMutex(timing_mutex);
677
#ifdef DEBUG_AUDIO 
678
                         printf("AUDIO: audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTime);
679
#endif
680
                }
681
        }
682

    
683
#ifdef DEBUG_AUDIO 
684
        if(audioq.first_pkt)
685
        {
686
                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);
687
                printf("AUDIO: QueueLen=%d ",(int)audioq.nb_packets);
688
                printf("AUDIO: QueueSize=%d\n",(int)audioq.size);
689
        }
690
        else
691
                printf("AUDIO: audio_decode_frame - Empty queue\n");
692
#endif
693

    
694

    
695
        if(audioq.nb_packets>0) {
696
                if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
697
                        SkipAudio = 1;
698
                        DecodeAudio = 0;
699
                }
700
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
701
                        (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
702
                                SkipAudio = 0;
703
                                DecodeAudio = 1;
704
                }
705
        }
706
                
707
        while(SkipAudio==1 && audioq.size>0) {
708
                SkipAudio = 0;
709
#ifdef DEBUG_AUDIO
710
                 printf("AUDIO: skipaudio: queue size=%d\n",audioq.size);
711
#endif
712
                if(PacketQueueGet(&audioq,&AudioPkt,1) < 0) {
713
                        return -1;
714
                }
715
                if(audioq.first_pkt)
716
                {
717
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
718
                                SkipAudio = 1;
719
                                DecodeAudio = 0;
720
                        }
721
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
722
                                (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
723
                                        SkipAudio = 0;
724
                                        DecodeAudio = 1;
725
                        }
726
                }
727
        }
728
        if(DecodeAudio==1) {
729
                if(PacketQueueGet(&audioq,&AudioPkt,1) < 0) {
730
                        return -1;
731
                }
732
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
733
                audio_pkt_size = AudioPkt.size;
734
#ifdef DEBUG_AUDIO
735
                 printf("AUDIO: Decode audio\n");
736
#endif
737
        }
738

    
739
        return audio_pkt_size;
740
}
741

    
742
int VideoCallback(void *valthread)
743
{
744
        //AVPacket pktvideo;
745
        AVCodecContext  *pCodecCtx;
746
        AVCodec         *pCodec;
747
        AVFrame         *pFrame;
748
        int frameFinished;
749
        AVPicture pict;
750
        long long Now;
751
        short int SkipVideo, DecodeVideo;
752

    
753
        //double frame_rate = 0.0,time_between_frames=0.0;
754
        //struct timeval now;
755

    
756
        //int wait_for_sync = 1;
757
        ThreadVal *tval;
758
        tval = (ThreadVal *)valthread;
759

    
760
        //frame_rate = tval->framerate;
761
        //time_between_frames = 1.e6 / frame_rate;
762
        //gettimeofday(&time_now,0);
763

    
764
        //frecon = fopen("recondechunk.mpg","wb");
765

    
766
        pCodecCtx=avcodec_alloc_context();
767
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
768
#ifdef H264_VIDEO_ENCODER
769
        pCodecCtx->codec_id  = CODEC_ID_H264;
770
        pCodecCtx->me_range = 16;
771
        pCodecCtx->max_qdiff = 4;
772
        pCodecCtx->qmin = 10;
773
        pCodecCtx->qmax = 51;
774
        pCodecCtx->qcompress = 0.6;
775
#else
776
        pCodecCtx->codec_id  = CODEC_ID_MPEG4;
777
#endif
778
        //pCodecCtx->bit_rate = 400000;
779
        // resolution must be a multiple of two
780
        pCodecCtx->width = tval->width;//176;//352;
781
        pCodecCtx->height = tval->height;//144;//288;
782
        
783
        // frames per second
784
        //pCodecCtx->time_base = (AVRational){1,25};
785
        //pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
786
        //pCodecCtx->max_b_frames=1;
787
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
788
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
789

    
790
        if(pCodec==NULL) {
791
                fprintf(stderr, "Unsupported codec!\n");
792
                return -1; // Codec not found
793
        }
794
        if(avcodec_open(pCodecCtx, pCodec) < 0) {
795
                fprintf(stderr, "could not open codec\n");
796
                return -1; // Could not open codec
797
        }
798
        pFrame=avcodec_alloc_frame();
799
        if(pFrame==NULL) {
800
                printf("Memory error!!!\n");
801
                return -1;
802
        }
803
        
804
#ifdef DEBUG_VIDEO
805
         printf("VIDEO: video_callback entering main cycle\n");
806
#endif
807
        while(AVPlaying && !quit) {
808
                if(QueueFillingMode || QueueStopped)
809
                {
810
                        //SDL_LockMutex(timing_mutex);
811
                        FirstTime = 1;
812
                        //SDL_UnlockMutex(timing_mutex);
813
                        usleep(5000);
814
                        continue;
815
                }
816

    
817
                DecodeVideo = 0;
818
                SkipVideo = 0;
819
                Now=(long long)SDL_GetTicks();
820
                if(FirstTime==1 && videoq.size>0) {
821
                        if(videoq.first_pkt->pkt.pts>0)
822
                        {
823
                                //SDL_LockMutex(timing_mutex);
824
                                DeltaTime=Now-(long long)videoq.first_pkt->pkt.pts;
825
                                FirstTime = 0;
826
                                //SDL_UnlockMutex(timing_mutex);
827
                        }
828
#ifdef DEBUG_VIDEO 
829
                         printf("VIDEO: VideoCallback - DeltaTimeAudio=%lld\n",DeltaTime);
830
#endif
831
                }
832

    
833
#ifdef DEBUG_VIDEO 
834
                if(videoq.first_pkt)
835
                {
836
                        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);
837
                        printf("VIDEO: Index=%d ", (int)videoq.first_pkt->pkt.stream_index);
838
                        printf("VIDEO: QueueLen=%d ", (int)videoq.nb_packets);
839
                        printf("VIDEO: QueueSize=%d\n", (int)videoq.size);
840
                }
841
                else
842
                        printf("VIDEO: VideoCallback - Empty queue\n");
843
#endif
844

    
845
                if(videoq.nb_packets>0) {
846
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)<Now-(long long)MAX_TOLLERANCE) {
847
                                SkipVideo = 1;
848
                                DecodeVideo = 0;
849
                        }
850
                        else 
851
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)>=Now-(long long)MAX_TOLLERANCE &&
852
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTime)<=Now+(long long)MAX_TOLLERANCE) {
853
                                        SkipVideo = 0;
854
                                        DecodeVideo = 1;
855
                                }
856
                }
857
#ifdef DEBUG_VIDEO
858
                printf("VIDEO: skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
859
#endif
860

    
861
                while(SkipVideo==1 && videoq.size>0) {
862
                        SkipVideo = 0;
863
#ifdef DEBUG_VIDEO 
864
                         printf("VIDEO: Skip Video\n");
865
#endif
866
                        if(PacketQueueGet(&videoq,&VideoPkt,0) < 0) {
867
                                break;
868
                        }
869
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
870
                        if(videoq.first_pkt)
871
                        {
872
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
873
                                        SkipVideo = 1;
874
                                        DecodeVideo = 0;
875
                                }
876
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
877
                                                                (long long)videoq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
878
                                        SkipVideo = 0;
879
                                        DecodeVideo = 1;
880
                                }
881
                        }
882
                }
883
                
884
                if(DecodeVideo==1) {
885
                        if(PacketQueueGet(&videoq,&VideoPkt,0) > 0) {
886

    
887
#ifdef DEBUG_VIDEO
888
                                printf("VIDEO: Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
889
#endif
890

    
891
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
892

    
893
                                if(frameFinished) { // it must be true all the time else error
894
#ifdef DEBUG_VIDEO
895
                                        printf("VIDEO: FrameFinished\n");
896
#endif
897
                                        if(SaveYUV)
898
                                                SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height);
899
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
900

    
901
                                        if(SilentMode)
902
                                                continue;
903

    
904
                                        // Lock SDL_yuv_overlay
905
                                        if(SDL_MUSTLOCK(MainScreen)) {
906
                                                if(SDL_LockSurface(MainScreen) < 0) {
907
                                                        continue;
908
                                                }
909
                                        }
910

    
911
                                        if(SDL_LockYUVOverlay(YUVOverlay) < 0) {
912
                                                if(SDL_MUSTLOCK(MainScreen)) {
913
                                                        SDL_UnlockSurface(MainScreen);
914
                                                }
915
                                                continue;
916
                                        }
917
                                        
918
                                        pict.data[0] = YUVOverlay->pixels[0];
919
                                        pict.data[1] = YUVOverlay->pixels[2];
920
                                        pict.data[2] = YUVOverlay->pixels[1];
921

    
922
                                        pict.linesize[0] = YUVOverlay->pitches[0];
923
                                        pict.linesize[1] = YUVOverlay->pitches[2];
924
                                        pict.linesize[2] = YUVOverlay->pitches[1];
925

    
926
                                        if(img_convert_ctx == NULL) {
927
                                                img_convert_ctx = sws_getContext(tval->width, tval->height, PIX_FMT_YUV420P, InitRect->w, InitRect->h, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
928
                                                if(img_convert_ctx == NULL) {
929
                                                        fprintf(stderr, "Cannot initialize the conversion context!\n");
930
                                                        exit(1);
931
                                                }
932
                                        }
933
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
934
                                        sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, tval->height, pict.data, pict.linesize);
935
                                        SDL_UnlockYUVOverlay(YUVOverlay);
936
                                        // Show, baby, show!
937
                                        SDL_LockMutex(OverlayMutex);
938
                                        SDL_DisplayYUVOverlay(YUVOverlay, &OverlayRect);
939
                                        SDL_UnlockMutex(OverlayMutex);
940

    
941
                                        //redisplay logo
942
                                        /**SDL_BlitSurface(image, NULL, MainScreen, &dest);*/
943
                                        /* Update the screen area just changed */
944
                                        /**SDL_UpdateRects(MainScreen, 1, &dest);*/
945

    
946
                                        if(SDL_MUSTLOCK(MainScreen)) {
947
                                                SDL_UnlockSurface(MainScreen);
948
                                        }
949
                                } //if FrameFinished
950
                        } // if packet_queue_get
951
                } //if DecodeVideo=1
952

    
953
                usleep(5000);
954
        }
955
        
956
        av_free(pCodecCtx);
957
        av_free(pFrame);
958
        //fclose(frecon);
959
#ifdef DEBUG_VIDEO
960
         printf("VIDEO: video callback end\n");
961
#endif
962
        return 0;
963
}
964

    
965
void AudioCallback(void *userdata, Uint8 *stream, int len)
966
{
967
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
968
        int audio_size;
969

    
970
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
971

    
972
        audio_size = AudioDecodeFrame(audio_buf, sizeof(audio_buf));
973
        if(audio_size != len) {
974
                memset(stream, 0, len);
975
        } else {
976
                memcpy(stream, (uint8_t *)audio_buf, len);
977
        }
978
}
979

    
980
void SaveFrame(AVFrame *pFrame, int width, int height)
981
{
982
        FILE *pFile;
983
        int  y;
984
  
985
         // Open file
986
        pFile=fopen(YUVFileName, "ab");
987
        if(pFile==NULL)
988
                return;
989
  
990
        // Write header
991
        //fprintf(pFile, "P5\n%d %d\n255\n", width, height);
992
  
993
        // Write Y data
994
        for(y=0; y<height; y++)
995
                  fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
996
        // Write U data
997
        for(y=0; y<height/2; y++)
998
                  fwrite(pFrame->data[1]+y*pFrame->linesize[1], 1, width/2, pFile);
999
        // Write V data
1000
        for(y=0; y<height/2; y++)
1001
                  fwrite(pFrame->data[2]+y*pFrame->linesize[2], 1, width/2, pFile);
1002
  
1003
        // Close file
1004
        fclose(pFile);
1005
}
1006

    
1007
int ChunkerPlayerCore_IsRunning()
1008
{
1009
        return AVPlaying;
1010
}
1011

    
1012
void ChunkerPlayerCore_Play()
1013
{
1014
        if(AVPlaying) return;
1015
        
1016
        AVPlaying = 1;
1017
        SDL_PauseAudio(0);
1018
        video_thread = SDL_CreateThread(VideoCallback, &VideoCallbackThreadParams);
1019
}
1020

    
1021
void ChunkerPlayerCore_Stop()
1022
{
1023
        if(!AVPlaying) return;
1024
        
1025
        AVPlaying = 0;
1026
        
1027
        // Stop audio&video playback
1028
        SDL_WaitThread(video_thread, NULL);
1029
        SDL_PauseAudio(1);
1030
        SDL_CloseAudio();
1031
        
1032
        if(YUVOverlay != NULL)
1033
        {
1034
                SDL_FreeYUVOverlay(YUVOverlay);
1035
                YUVOverlay = NULL;
1036
        }
1037
        
1038
        PacketQueueReset(&audioq, AUDIO);
1039
        PacketQueueReset(&videoq, VIDEO);
1040
        
1041
        av_free(aCodecCtx);
1042
        free(AudioPkt.data);
1043
        free(VideoPkt.data);
1044
        free(outbuf_audio);
1045
        free(InitRect);
1046
}
1047

    
1048
int ChunkerPlayerCore_AudioEnded()
1049
{
1050
        return (audioq.nb_packets==0 && audioq.last_frame_extracted>0);
1051
}
1052

    
1053
void ChunkerPlayerCore_ResetAVQueues()
1054
{
1055
#ifdef DEBUG_QUEUE
1056
        printf("QUEUE: MAIN SHOULD RESET\n");
1057
#endif
1058
        PacketQueueReset(&audioq, AUDIO);
1059
        PacketQueueReset(&videoq, VIDEO);
1060
}
1061

    
1062
int ChunkerPlayerCore_EnqueueBlocks(const uint8_t *block, const int block_size)
1063
{
1064
        Chunk *gchunk = NULL;
1065
        ExternalChunk *echunk = NULL;
1066
        int decoded_size = -1;
1067
        uint8_t *tempdata, *buffer;
1068
        int j;
1069
        Frame *frame = NULL;
1070
        AVPacket packet, packetaudio;
1071

    
1072
        uint16_t *audio_bufQ = NULL;
1073

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

    
1078
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1079
        if(!audio_bufQ) {
1080
                printf("Memory error in audio_bufQ!\n");
1081
                return PLAYER_FAIL_RETURN;
1082
        }
1083

    
1084
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1085
        if(!gchunk) {
1086
                printf("Memory error in gchunk!\n");
1087
                av_free(audio_bufQ);
1088
                return PLAYER_FAIL_RETURN;
1089
        }
1090

    
1091
        decoded_size = decodeChunk(gchunk, block, block_size);
1092
#ifdef DEBUG_CHUNKER
1093
        printf("CHUNKER: enqueueBlock: decoded_size %d target size %d\n", decoded_size, GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size);
1094
#endif
1095
  if(decoded_size < 0 || decoded_size != GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size) {
1096
                //HINT here i should differentiate between various return values of the decode
1097
                //in order to free what has been allocated there
1098
                printf("chunk probably corrupted!\n");
1099
                av_free(audio_bufQ);
1100
                free(gchunk);
1101
                return PLAYER_FAIL_RETURN;
1102
        }
1103

    
1104
        echunk = grapesChunkToExternalChunk(gchunk);
1105
        if(echunk == NULL) {
1106
                printf("Memory error in echunk!\n");
1107
                free(gchunk->attributes);
1108
                free(gchunk->data);
1109
                free(gchunk);
1110
                return PLAYER_FAIL_RETURN;
1111
        }
1112
        free(gchunk->attributes);
1113
        free(gchunk);
1114

    
1115
        frame = (Frame *)malloc(sizeof(Frame));
1116
        if(!frame) {
1117
                printf("Memory error in Frame!\n");
1118
                if(gchunk->attributes)
1119
                        free(gchunk->attributes);
1120
                if(echunk->data)
1121
                        free(echunk->data);
1122
                if(echunk)
1123
                        free(echunk);
1124
                av_free(audio_bufQ);
1125
                return PLAYER_FAIL_RETURN;
1126
        }
1127

    
1128
        tempdata = echunk->data; //let it point to first frame of payload
1129
        j=echunk->payload_len;
1130
        while(j>0 && !quit) {
1131
                frame->number = bit32_encoded_pull(tempdata);
1132
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1133
                frame->timestamp.tv_sec = bit32_encoded_pull(tempdata);
1134
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1135
                frame->timestamp.tv_usec = bit32_encoded_pull(tempdata);
1136
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1137
                frame->size = bit32_encoded_pull(tempdata);
1138
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1139
                frame->type = bit32_encoded_pull(tempdata);
1140
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1141

    
1142
                buffer = tempdata; // here coded frame information
1143
                tempdata += frame->size; //let it point to the next frame
1144

    
1145
                if(frame->type < 5) { // video frame
1146
                        av_init_packet(&packet);
1147
                        packet.data = buffer;//video_bufQ;
1148
                        packet.size = frame->size;
1149
                        packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1150
                        packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1151
                        packet.stream_index = frame->number; // use of stream_index for number frame
1152
                        //packet.duration = frame->timestamp.tv_sec;
1153
                        if(packet.size > 0)
1154
                                ChunkerPlayerCore_PacketQueuePut(&videoq, &packet); //the _put makes a copy of the packet
1155

    
1156
#ifdef DEBUG_SOURCE
1157
                        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);
1158
#endif
1159
                }
1160
                else if(frame->type == 5) { // audio frame
1161
                        av_init_packet(&packetaudio);
1162
                        packetaudio.data = buffer;
1163
                        packetaudio.size = frame->size;
1164
                        packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1165
                        packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1166
                        //packetaudio.duration = frame->timestamp.tv_sec;
1167
                        packetaudio.stream_index = frame->number; // use of stream_index for number frame
1168
                        packetaudio.flags = 1;
1169
                        packetaudio.pos = -1;
1170

    
1171
                        //instead of -1, in order to signal it is not decoded yet
1172
                        packetaudio.convergence_duration = 0;
1173

    
1174
                        // insert the audio frame into the queue
1175
                        if(packetaudio.size > 0)
1176
                                ChunkerPlayerCore_PacketQueuePut(&audioq, &packetaudio);//makes a copy of the packet so i can free here
1177

    
1178
#ifdef DEBUG_SOURCE
1179
                        printf("SOURCE: Insert audio in queue pts=%lld sindex:%d\n", packetaudio.pts, packetaudio.stream_index);
1180
#endif
1181
                }
1182
                else {
1183
                        printf("SOURCE: Unknown frame type %d. Size %d\n", frame->type, frame->size);
1184
                }
1185
                if(frame->size > 0)
1186
                        j = j - sizeFrameHeader - frame->size;
1187
                else {
1188
                        printf("SOURCE: Corrupt frames (size %d) in chunk. Skipping it...\n", frame->size);
1189
                        j = -1;
1190
                }
1191
        }
1192
        //chunk ingestion terminated!
1193
        if(echunk->data)
1194
                free(echunk->data);
1195
        if(echunk)
1196
                free(echunk);
1197
        if(frame)
1198
                free(frame);
1199
        if(audio_bufQ)
1200
                av_free(audio_bufQ);
1201
                
1202
        return PLAYER_OK_RETURN;
1203
}
1204

    
1205
void ChunkerPlayerCore_SetupOverlay(int width, int height)
1206
{
1207
        // if(!MainScreen && !SilentMode)
1208
        // {
1209
                // printf("Cannot find main screen, exiting...\n");
1210
                // exit(1);
1211
        // }
1212
        
1213
        if(SilentMode)
1214
                return;
1215
                
1216
        SDL_LockMutex(OverlayMutex);
1217
        if(YUVOverlay != NULL)
1218
        {
1219
                SDL_FreeYUVOverlay(YUVOverlay);
1220
                YUVOverlay = NULL;
1221
        }
1222
        
1223
        // create video overlay for display of video frames
1224
        // printf("SDL_CreateYUVOverlay(%d, %d, SDL_YV12_OVERLAY, MainScreen)\n", width, height);
1225
        YUVOverlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, MainScreen);
1226
        // YUVOverlay = SDL_CreateYUVOverlay(OverlayRect.w, OverlayRect.h, SDL_YV12_OVERLAY, MainScreen);
1227
        if ( YUVOverlay == NULL )
1228
        {
1229
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
1230
                exit(1);
1231
        }
1232

    
1233
        if ( YUVOverlay->hw_overlay )
1234
                fprintf(stderr,"SDL: Using hardware overlay.\n");
1235
        // OverlayRect.x = (screen_w - width) / 2;
1236
        
1237
        SDL_DisplayYUVOverlay(YUVOverlay, &OverlayRect);
1238
        
1239
        SDL_UnlockMutex(OverlayMutex);
1240
}