Statistics
| Branch: | Revision:

chunker-player / chunker_player / player_core.c @ 5ca3d85e

History | View | Annotate | Download (34.8 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)
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
                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=%d LastExtr=%d\n", q->nb_packets, q->queueType, 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=%d, RESETTING\n", q->nb_packets, q->queueType);
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=%d\n",q->nb_packets, q->queueType);
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=%d\n", q->nb_packets, q->queueType);
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
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
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
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
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
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
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
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
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
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 LastFrameExtracted = %d\n",q->last_frame_extracted);
648
        printf("QUEUE: Get Tot lost frames = %d\n",q->total_lost_frames);
649
#endif
650

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

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

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

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

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

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

    
700

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

    
745
        return audio_pkt_size;
746
}
747

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
907
                                        if(SilentMode)
908
                                                continue;
909

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

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

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

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

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

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

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

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

    
976
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
977

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

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

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

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

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

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

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

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

    
1080
        uint16_t *audio_bufQ = NULL;
1081

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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