Statistics
| Branch: | Revision:

chunker-player / chunker_player / player_core.c @ 730c29f4

History | View | Annotate | Download (35 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=%s\n", q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO");
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=%s\n", q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO");
33
#endif
34
}
35

    
36
void PacketQueueReset(PacketQueue *q)
37
{
38
        AVPacketList *tmp,*tmp1;
39
#ifdef DEBUG_QUEUE
40
        printf("QUEUE: RESET BEGIN: NPackets=%d Type=%s LastExtr=%d\n", q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO", 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
                q->total_lost_frames++;
54
        }
55
#ifdef DEBUG_QUEUE
56
        printf("\n");
57
#endif
58

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

    
78
int ChunkerPlayerCore_PacketQueuePut(PacketQueue *q, AVPacket *pkt)
79
{
80
        short int skip = 0;
81
        AVPacketList *pkt1, *tmp, *prevtmp;
82

    
83
        if(q->nb_packets > queue_filling_threshold*QUEUE_MAX_GROW_FACTOR) {
84
#ifdef DEBUG_QUEUE
85
                printf("QUEUE: PUT i have TOO MANY packets %d Type=%s, RESETTING\n", q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO");
86
#endif
87
                PacketQueueReset(q);
88
  }
89

    
90
        //make a copy of the incoming packet
91
        if(av_dup_packet(pkt) < 0) {
92
#ifdef DEBUG_QUEUE
93
                printf("QUEUE: PUT in Queue cannot duplicate in packet        : NPackets=%d Type=%s\n",q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO");
94
#endif
95
                return -1;
96
        }
97
        pkt1 = av_malloc(sizeof(AVPacketList));
98

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

    
106
        SDL_LockMutex(q->mutex);
107

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

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

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

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

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

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

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

    
247
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
248

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

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

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

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

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

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

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

    
454
void UpdateLossTraces(int type, int first_lost, int n_lost)
455
{
456
        FILE *lossFile;
457
        int i;
458

    
459
        // Open loss traces file
460
        char filename[255];
461
        if(type == AUDIO)
462
                sprintf(filename, "audio_%s", LossTracesFilename);
463
        else
464
                sprintf(filename, "video_%s", LossTracesFilename);
465

    
466
        lossFile=fopen(filename, "a");
467
        if(lossFile==NULL) {
468
                printf("STATS: UNABLE TO OPEN Loss FILE: %s\n", filename);
469
                return;
470
        }
471

    
472
        for(i=0; i<n_lost; i++) {
473
                fprintf(lossFile, "%d\n", first_lost+i);
474
        }
475

    
476
        fclose(lossFile);
477
}
478

    
479
int PacketQueueGet(PacketQueue *q, AVPacket *pkt, short int av) {
480
        //AVPacket tmp;
481
        AVPacketList *pkt1 = NULL;
482
        int ret=-1;
483
        int SizeToCopy=0;
484

    
485
        SDL_LockMutex(q->mutex);
486

    
487
#ifdef DEBUG_QUEUE
488
        printf("QUEUE: Get NPackets=%d Type=%s\n", q->nb_packets, (q->queueType==AUDIO) ? "AUDIO" : "VIDEO");
489
#endif
490

    
491
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
492
        {
493
                SDL_UnlockMutex(q->mutex);
494
                return -1;
495
        }
496

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

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

    
625
                        //HINT SEE BEFORE q->size -= pkt1->pkt.size;
626
                        q->first_pkt = RemoveFromQueue(q, pkt1);
627

    
628
                        ret = 1;
629
                        UpdateQueueStats(q, pkt->stream_index);
630
                        //update index of last frame extracted
631
                        q->last_frame_extracted = pkt->stream_index;
632
                }
633
#ifdef DEBUG_QUEUE
634
                else {
635
                        printf("  VIDEO pk1 NULL!!!!\n");
636
                }
637
#endif
638
        }
639

    
640
        if(q->nb_packets==0 && q->queueType==AUDIO) {
641
                QueueFillingMode=1;
642
#ifdef DEBUG_QUEUE
643
                printf("QUEUE: Get FillingMode ON\n");
644
#endif
645
        }
646
#ifdef DEBUG_QUEUE
647
        printf("QUEUE: Get Last %s Frame Extracted = %d\n", (q->queueType==AUDIO) ? "AUDIO" : "VIDEO", q->last_frame_extracted);
648
#endif
649

    
650
        SDL_UnlockMutex(q->mutex);
651
        return ret;
652
}
653

    
654
int AudioDecodeFrame(uint8_t *audio_buf, int buf_size) {
655
        //struct timeval now;
656
        int audio_pkt_size = 0;
657
        long long Now;
658
        short int DecodeAudio=0, SkipAudio=0;
659
        //int len1, data_size;
660

    
661
        //gettimeofday(&now,NULL);
662
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
663
        Now=(long long)SDL_GetTicks();
664

    
665
        if(QueueFillingMode || QueueStopped)
666
        {
667
                //SDL_LockMutex(timing_mutex);
668
                FirstTimeAudio=1;
669
                FirstTime = 1;
670
                //SDL_UnlockMutex(timing_mutex);
671
                return -1;
672
        }
673

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

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

    
699

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

    
744
        return audio_pkt_size;
745
}
746

    
747
int VideoCallback(void *valthread)
748
{
749
        //AVPacket pktvideo;
750
        AVCodecContext  *pCodecCtx;
751
        AVCodec         *pCodec;
752
        AVFrame         *pFrame;
753
        int frameFinished;
754
        AVPicture pict;
755
        long long Now;
756
        short int SkipVideo, DecodeVideo;
757

    
758
        //double frame_rate = 0.0,time_between_frames=0.0;
759
        //struct timeval now;
760

    
761
        //int wait_for_sync = 1;
762
        ThreadVal *tval;
763
        tval = (ThreadVal *)valthread;
764

    
765
        //frame_rate = tval->framerate;
766
        //time_between_frames = 1.e6 / frame_rate;
767
        //gettimeofday(&time_now,0);
768

    
769
        //frecon = fopen("recondechunk.mpg","wb");
770

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

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

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

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

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

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

    
892
#ifdef DEBUG_VIDEO
893
                                printf("VIDEO: Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
894
#endif
895

    
896
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
897

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

    
906
                                        if(SilentMode)
907
                                                continue;
908

    
909
                                        // Lock SDL_yuv_overlay
910
                                        if(SDL_MUSTLOCK(MainScreen)) {
911
                                                if(SDL_LockSurface(MainScreen) < 0) {
912
                                                        continue;
913
                                                }
914
                                        }
915

    
916
                                        if(SDL_LockYUVOverlay(YUVOverlay) < 0) {
917
                                                if(SDL_MUSTLOCK(MainScreen)) {
918
                                                        SDL_UnlockSurface(MainScreen);
919
                                                }
920
                                                continue;
921
                                        }
922
                                        
923
                                        pict.data[0] = YUVOverlay->pixels[0];
924
                                        pict.data[1] = YUVOverlay->pixels[2];
925
                                        pict.data[2] = YUVOverlay->pixels[1];
926

    
927
                                        pict.linesize[0] = YUVOverlay->pitches[0];
928
                                        pict.linesize[1] = YUVOverlay->pitches[2];
929
                                        pict.linesize[2] = YUVOverlay->pitches[1];
930

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

    
946
                                        //redisplay logo
947
                                        /**SDL_BlitSurface(image, NULL, MainScreen, &dest);*/
948
                                        /* Update the screen area just changed */
949
                                        /**SDL_UpdateRects(MainScreen, 1, &dest);*/
950

    
951
                                        if(SDL_MUSTLOCK(MainScreen)) {
952
                                                SDL_UnlockSurface(MainScreen);
953
                                        }
954
                                } //if FrameFinished
955
                        } // if packet_queue_get
956
                } //if DecodeVideo=1
957

    
958
                usleep(5000);
959
        }
960
        
961
        av_free(pCodecCtx);
962
        av_free(pFrame);
963
        //fclose(frecon);
964
#ifdef DEBUG_VIDEO
965
         printf("VIDEO: video callback end\n");
966
#endif
967
        return 0;
968
}
969

    
970
void AudioCallback(void *userdata, Uint8 *stream, int len)
971
{
972
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
973
        int audio_size;
974

    
975
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
976

    
977
        audio_size = AudioDecodeFrame(audio_buf, sizeof(audio_buf));
978
        
979
        if(!SilentMode)
980
                if(audio_size != len) {
981
                        memset(stream, 0, len);
982
                } else {
983
                        memcpy(stream, (uint8_t *)audio_buf, len);
984
                }
985
}
986

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

    
1014
int ChunkerPlayerCore_IsRunning()
1015
{
1016
        return AVPlaying;
1017
}
1018

    
1019
void ChunkerPlayerCore_Play()
1020
{
1021
        if(AVPlaying) return;
1022
        
1023
        AVPlaying = 1;
1024
        SDL_PauseAudio(0);
1025
        video_thread = SDL_CreateThread(VideoCallback, &VideoCallbackThreadParams);
1026
}
1027

    
1028
void ChunkerPlayerCore_Stop()
1029
{
1030
        if(!AVPlaying) return;
1031
        
1032
        AVPlaying = 0;
1033
        
1034
        // Stop audio&video playback
1035
        SDL_WaitThread(video_thread, NULL);
1036
        SDL_PauseAudio(1);
1037
        SDL_CloseAudio();
1038
        
1039
        if(YUVOverlay != NULL)
1040
        {
1041
                SDL_FreeYUVOverlay(YUVOverlay);
1042
                YUVOverlay = NULL;
1043
        }
1044
        
1045
        PacketQueueReset(&audioq);
1046
        PacketQueueReset(&videoq);
1047
        
1048
        av_free(aCodecCtx);
1049
        free(AudioPkt.data);
1050
        free(VideoPkt.data);
1051
        free(outbuf_audio);
1052
        free(InitRect);
1053
}
1054

    
1055
int ChunkerPlayerCore_AudioEnded()
1056
{
1057
        return (audioq.nb_packets==0 && audioq.last_frame_extracted>0);
1058
}
1059

    
1060
void ChunkerPlayerCore_ResetAVQueues()
1061
{
1062
#ifdef DEBUG_QUEUE
1063
        printf("QUEUE: MAIN SHOULD RESET\n");
1064
#endif
1065
        PacketQueueReset(&audioq);
1066
        PacketQueueReset(&videoq);
1067
}
1068

    
1069
int ChunkerPlayerCore_EnqueueBlocks(const uint8_t *block, const int block_size)
1070
{
1071
        Chunk *gchunk = NULL;
1072
        ExternalChunk *echunk = NULL;
1073
        int decoded_size = -1;
1074
        uint8_t *tempdata, *buffer;
1075
        int j;
1076
        Frame *frame = NULL;
1077
        AVPacket packet, packetaudio;
1078

    
1079
        uint16_t *audio_bufQ = NULL;
1080

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

    
1085
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1086
        if(!audio_bufQ) {
1087
                printf("Memory error in audio_bufQ!\n");
1088
                return PLAYER_FAIL_RETURN;
1089
        }
1090

    
1091
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1092
        if(!gchunk) {
1093
                printf("Memory error in gchunk!\n");
1094
                av_free(audio_bufQ);
1095
                return PLAYER_FAIL_RETURN;
1096
        }
1097

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

    
1111
        echunk = grapesChunkToExternalChunk(gchunk);
1112
        if(echunk == NULL) {
1113
                printf("Memory error in echunk!\n");
1114
                free(gchunk->attributes);
1115
                free(gchunk->data);
1116
                free(gchunk);
1117
                return PLAYER_FAIL_RETURN;
1118
        }
1119
        free(gchunk->attributes);
1120
        free(gchunk);
1121

    
1122
        frame = (Frame *)malloc(sizeof(Frame));
1123
        if(!frame) {
1124
                printf("Memory error in Frame!\n");
1125
                if(gchunk->attributes)
1126
                        free(gchunk->attributes);
1127
                if(echunk->data)
1128
                        free(echunk->data);
1129
                if(echunk)
1130
                        free(echunk);
1131
                av_free(audio_bufQ);
1132
                return PLAYER_FAIL_RETURN;
1133
        }
1134

    
1135
        tempdata = echunk->data; //let it point to first frame of payload
1136
        j=echunk->payload_len;
1137
        while(j>0 && !quit) {
1138
                frame->number = bit32_encoded_pull(tempdata);
1139
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1140
                frame->timestamp.tv_sec = bit32_encoded_pull(tempdata);
1141
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1142
                frame->timestamp.tv_usec = bit32_encoded_pull(tempdata);
1143
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1144
                frame->size = bit32_encoded_pull(tempdata);
1145
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1146
                frame->type = bit32_encoded_pull(tempdata);
1147
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1148

    
1149
                buffer = tempdata; // here coded frame information
1150
                tempdata += frame->size; //let it point to the next frame
1151

    
1152
                if(frame->type < 5) { // video frame
1153
                        av_init_packet(&packet);
1154
                        packet.data = buffer;//video_bufQ;
1155
                        packet.size = frame->size;
1156
                        packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1157
                        packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1158
                        packet.stream_index = frame->number; // use of stream_index for number frame
1159
                        //packet.duration = frame->timestamp.tv_sec;
1160
                        if(packet.size > 0)
1161
                                ChunkerPlayerCore_PacketQueuePut(&videoq, &packet); //the _put makes a copy of the packet
1162

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

    
1178
                        //instead of -1, in order to signal it is not decoded yet
1179
                        packetaudio.convergence_duration = 0;
1180

    
1181
                        // insert the audio frame into the queue
1182
                        if(packetaudio.size > 0)
1183
                                ChunkerPlayerCore_PacketQueuePut(&audioq, &packetaudio);//makes a copy of the packet so i can free here
1184

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

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

    
1240
        if ( YUVOverlay->hw_overlay )
1241
                fprintf(stderr,"SDL: Using hardware overlay.\n");
1242
        // OverlayRect.x = (screen_w - width) / 2;
1243
        
1244
        SDL_DisplayYUVOverlay(YUVOverlay, &OverlayRect);
1245
        
1246
        SDL_UnlockMutex(OverlayMutex);
1247
}