Statistics
| Branch: | Revision:

chunker-player / chunker_player.c @ 0f001772

History | View | Annotate | Download (34 KB)

1 1e69ae95 GiuseppeTropea
// player.c
2
// Author 
3 34149271 GiuseppeTropea
// Diego Reforgiato, Dario Marchese, Carmelo Daniele, Giuseppe Tropea
4 1e69ae95 GiuseppeTropea
//
5
// Use the file compile to compile the program to build (assuming libavformat and libavcodec are 
6
// correctly installed your system).
7
//
8
// Run using
9
//
10
// player <width> <height>
11
12
#include <libavcodec/avcodec.h>
13
#include <libavformat/avformat.h>
14
#include <libswscale/swscale.h>
15
16
#include <stdio.h>
17
#include <dirent.h>
18
#include <string.h>
19
#include <stdlib.h>
20
#include <sys/time.h>
21
#include <unistd.h>
22
#include <signal.h>
23
#include <SDL.h>
24
#include <SDL_thread.h>
25
#include <SDL_mutex.h>
26
27 f126ff44 GiuseppeTropea
28 1e69ae95 GiuseppeTropea
#ifdef __MINGW32__
29
#undef main /* Prevents SDL from overriding main() */
30
#endif
31
32 e810bf7b GiuseppeTropea
#include <platform.h>
33
#include <microhttpd.h>
34
35 1e69ae95 GiuseppeTropea
#include "chunker_player.h"
36 e810bf7b GiuseppeTropea
#include "codec_definitions.h"
37 1e69ae95 GiuseppeTropea
38
#define SDL_AUDIO_BUFFER_SIZE 1024
39
40 34149271 GiuseppeTropea
#define MAX_TOLLERANCE 40
41 1e69ae95 GiuseppeTropea
#define AUDIO        1
42
#define VIDEO        2
43
44 0f001772 GiuseppeTropea
//#define DEBUG_AUDIO
45
//#define DEBUG_VIDEO
46
//#define DEBUG_QUEUE
47
//#define DEBUG_SOURCE
48 e08af472 GiuseppeTropea
#define DEBUG_STATS
49 0f001772 GiuseppeTropea
//#define DEBUG_AUDIO_BUFFER
50
//#define DEBUG_CHUNKER
51 88fe20d0 GiuseppeTropea
52 1e69ae95 GiuseppeTropea
53
short int QueueFillingMode=1;
54
short int QueueStopped=0;
55
56
typedef struct PacketQueue {
57 f126ff44 GiuseppeTropea
        AVPacketList *first_pkt;
58
        //AVPacketList *last_pkt;
59 1e69ae95 GiuseppeTropea
        int nb_packets;
60
        int size;
61
        SDL_mutex *mutex;
62
        short int queueType;
63 34149271 GiuseppeTropea
        int last_frame_extracted; //HINT THIS SHOULD BE MORE THAN 4 BYTES
64 e810bf7b GiuseppeTropea
        int total_lost_frames;
65 1e69ae95 GiuseppeTropea
} PacketQueue;
66
67
typedef struct threadVal {
68
        int width;
69
        int height;
70
} ThreadVal;
71
72
int AudioQueueOffset=0;
73
PacketQueue audioq;
74
PacketQueue videoq;
75
AVPacket AudioPkt, VideoPkt;
76
int quit = 0;
77
78 af501115 GiuseppeTropea
int queue_filling_threshold = 0;
79
80 1e69ae95 GiuseppeTropea
SDL_Surface *screen;
81
SDL_Overlay *yuv_overlay;
82
SDL_Rect    rect;
83 f126ff44 GiuseppeTropea
SDL_AudioSpec spec;
84 34149271 GiuseppeTropea
struct SwsContext *img_convert_ctx = NULL;
85
//SDL_mutex *timing_mutex;
86 1e69ae95 GiuseppeTropea
87
int got_sigint = 0;
88
89 f9cf0a8d GiuseppeTropea
long long DeltaTime;
90 34149271 GiuseppeTropea
short int FirstTimeAudio=1, FirstTime = 1;
91 1e69ae95 GiuseppeTropea
92
int dimAudioQ;
93
float deltaAudioQ;
94 34149271 GiuseppeTropea
float deltaAudioQError=0;
95 1e69ae95 GiuseppeTropea
96
void packet_queue_init(PacketQueue *q, short int Type) {
97 34149271 GiuseppeTropea
#ifdef DEBUG_QUEUE
98
        printf("QUEUE: INIT BEGIN: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
99
#endif
100 1e69ae95 GiuseppeTropea
        memset(q,0,sizeof(PacketQueue));
101
        q->mutex = SDL_CreateMutex();
102
        QueueFillingMode=1;
103
        q->queueType=Type;
104 88fe20d0 GiuseppeTropea
        q->last_frame_extracted = -1;
105 e810bf7b GiuseppeTropea
        q->total_lost_frames = 0;
106 34149271 GiuseppeTropea
        q->first_pkt= NULL;
107 f126ff44 GiuseppeTropea
        //q->last_pkt = NULL;
108 34149271 GiuseppeTropea
        q->nb_packets = 0;
109
        q->size = 0;
110
        FirstTime = 1;
111
        FirstTimeAudio = 1;
112
#ifdef DEBUG_QUEUE
113
        printf("QUEUE: INIT END: NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
114
#endif
115
}
116
117
void packet_queue_reset(PacketQueue *q, short int Type) {
118
        AVPacketList *tmp,*tmp1;
119
#ifdef DEBUG_QUEUE
120
        printf("QUEUE: RESET BEGIN: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
121
#endif
122
        SDL_LockMutex(q->mutex);
123
124
        tmp = q->first_pkt;
125
        while(tmp) {
126
                tmp1 = tmp;
127
                tmp = tmp->next;
128
                av_free_packet(&(tmp1->pkt));
129
                av_free(tmp1);
130
#ifdef DEBUG_QUEUE
131
        printf("F ");
132
#endif
133
        }
134
#ifdef DEBUG_QUEUE
135
        printf("\n");
136
#endif
137
138
        QueueFillingMode=1;
139 88fe20d0 GiuseppeTropea
        q->last_frame_extracted = -1;
140 34149271 GiuseppeTropea
        q->total_lost_frames = 0;
141
        q->first_pkt= NULL;
142 f126ff44 GiuseppeTropea
        //q->last_pkt = NULL;
143 34149271 GiuseppeTropea
        q->nb_packets = 0;
144
        q->size = 0;
145
        FirstTime = 1;
146
        FirstTimeAudio = 1;
147
#ifdef DEBUG_QUEUE
148
        printf("QUEUE: RESET END: NPackets=%d Type=%d LastExtr=%d\n", q->nb_packets, q->queueType, q->last_frame_extracted);
149
#endif
150
        SDL_UnlockMutex(q->mutex);
151 1e69ae95 GiuseppeTropea
}
152
153
int packet_queue_put(PacketQueue *q, AVPacket *pkt) {
154 f9cf0a8d GiuseppeTropea
        short int skip = 0;
155
        AVPacketList *pkt1, *tmp, *prevtmp;
156 34149271 GiuseppeTropea
157
        //make a copy of the incoming packet
158 1e69ae95 GiuseppeTropea
        if(av_dup_packet(pkt) < 0) {
159 34149271 GiuseppeTropea
#ifdef DEBUG_QUEUE
160 88fe20d0 GiuseppeTropea
                printf("QUEUE: PUT in Queue cannot duplicate in packet        : NPackets=%d Type=%d\n",q->nb_packets, q->queueType);
161 34149271 GiuseppeTropea
#endif
162 1e69ae95 GiuseppeTropea
                return -1;
163
        }
164
        pkt1 = av_malloc(sizeof(AVPacketList));
165 34149271 GiuseppeTropea
166
        if(!pkt1) {
167
                av_free_packet(pkt);
168 1e69ae95 GiuseppeTropea
                return -1;
169 34149271 GiuseppeTropea
        }
170 1e69ae95 GiuseppeTropea
        pkt1->pkt = *pkt;
171
        pkt1->next = NULL;
172
173
        SDL_LockMutex(q->mutex);
174
175 34149271 GiuseppeTropea
        // INSERTION SORT ALGORITHM
176
        // before inserting pkt, check if pkt.stream_index is <= current_extracted_frame.
177 88fe20d0 GiuseppeTropea
        if(pkt->stream_index > q->last_frame_extracted) {
178 34149271 GiuseppeTropea
                // either checking starting from the first_pkt or needed other struct like AVPacketList with next and prev....
179 f126ff44 GiuseppeTropea
                //if (!q->last_pkt)
180
                if(!q->first_pkt)
181 f9cf0a8d GiuseppeTropea
                        q->first_pkt = pkt1;
182 f126ff44 GiuseppeTropea
                else if(pkt->stream_index < q->first_pkt->pkt.stream_index) {
183
                        //the packet that has arrived is earlier than the first we got some time ago!
184
                        //we need to put it at the head of the queue
185
                        pkt1->next = q->first_pkt;
186
                        q->first_pkt = pkt1;
187
                }
188 f9cf0a8d GiuseppeTropea
                else {
189
                        tmp = q->first_pkt;
190 88fe20d0 GiuseppeTropea
                        while(tmp->pkt.stream_index < pkt->stream_index) {
191 f9cf0a8d GiuseppeTropea
                                prevtmp = tmp;
192
                                tmp = tmp->next;
193 34149271 GiuseppeTropea
194 f126ff44 GiuseppeTropea
                                if(!tmp) {
195 f9cf0a8d GiuseppeTropea
                                        break;
196 f126ff44 GiuseppeTropea
                                }
197 f9cf0a8d GiuseppeTropea
                        }
198 88fe20d0 GiuseppeTropea
                        if(tmp && tmp->pkt.stream_index == pkt->stream_index) {
199 34149271 GiuseppeTropea
                                //we already have a frame with that index
200 f9cf0a8d GiuseppeTropea
                                skip = 1;
201 34149271 GiuseppeTropea
#ifdef DEBUG_QUEUE
202 f126ff44 GiuseppeTropea
                                printf("QUEUE: PUT: we already have frame with index %d, skipping\n", pkt->stream_index);
203 34149271 GiuseppeTropea
#endif
204 f9cf0a8d GiuseppeTropea
                        }
205
                        else {
206
                                prevtmp->next = pkt1;
207
                                pkt1->next = tmp;
208
                        }
209 34149271 GiuseppeTropea
                        //q->last_pkt->next = pkt1; // It was uncommented when not insertion sort
210 f9cf0a8d GiuseppeTropea
                }
211 88fe20d0 GiuseppeTropea
                if(skip == 0) {
212 f126ff44 GiuseppeTropea
                        //q->last_pkt = pkt1;
213 f9cf0a8d GiuseppeTropea
                        q->nb_packets++;
214
                        q->size += pkt1->pkt.size;
215 af501115 GiuseppeTropea
                        if(q->nb_packets>=queue_filling_threshold && QueueFillingMode) // && q->queueType==AUDIO)
216 f9cf0a8d GiuseppeTropea
                        {
217
                                QueueFillingMode=0;
218 e810bf7b GiuseppeTropea
#ifdef DEBUG_QUEUE
219 34149271 GiuseppeTropea
                                printf("QUEUE: PUT: FillingMode set to zero\n");
220 e810bf7b GiuseppeTropea
#endif
221 f9cf0a8d GiuseppeTropea
                        }
222
                }
223 1e69ae95 GiuseppeTropea
        }
224 34149271 GiuseppeTropea
        else {
225
                av_free_packet(&pkt1->pkt);
226
                av_free(pkt1);
227
#ifdef DEBUG_QUEUE
228
                                printf("QUEUE: PUT: NOT inserting because index %d > last extracted %d\n", pkt->stream_index, q->last_frame_extracted);
229
#endif
230
        }
231 1e69ae95 GiuseppeTropea
232
        SDL_UnlockMutex(q->mutex);
233
        return 0;
234
}
235
236 f126ff44 GiuseppeTropea
237 88fe20d0 GiuseppeTropea
int decode_enqueued_audio_packet(AVPacket *pkt, PacketQueue *q) {
238 f126ff44 GiuseppeTropea
        uint16_t *audio_bufQ = NULL;
239
        int16_t *dataQ = NULL;
240
        int data_sizeQ = AVCODEC_MAX_AUDIO_FRAME_SIZE;
241
        int lenQ;
242 d0819384 GiuseppeTropea
        int ret = 0;
243 f126ff44 GiuseppeTropea
244
        //set the flag to decoded anyway        
245
        pkt->convergence_duration = -1;
246
247
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
248
        if(audio_bufQ) {
249
#ifdef DEBUG_AUDIO_BUFFER
250 88fe20d0 GiuseppeTropea
                printf("AUDIO_BUFFER: about to decode packet %d, size %d, data %d\n", pkt->stream_index, pkt->size, pkt->data);
251 f126ff44 GiuseppeTropea
#endif
252
                //decode the packet data
253
                lenQ = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_bufQ, &data_sizeQ, pkt);
254
                if(lenQ > 0) {
255
                        dataQ = (int16_t *)av_malloc(data_sizeQ); //this will be free later at the time of playback
256
                        if(dataQ) {
257
                                memcpy(dataQ, audio_bufQ, data_sizeQ);
258 88fe20d0 GiuseppeTropea
                                //discard the old encoded bytes
259 f126ff44 GiuseppeTropea
                                av_free(pkt->data);
260 88fe20d0 GiuseppeTropea
                                //subtract them from queue size
261
                                q->size -= pkt->size;
262 f126ff44 GiuseppeTropea
                                pkt->data = (int8_t *)dataQ;
263
                                pkt->size = data_sizeQ;
264 88fe20d0 GiuseppeTropea
                                //add new size to queue size
265
                                q->size += pkt->size;
266 d0819384 GiuseppeTropea
                                ret = 1;
267 f126ff44 GiuseppeTropea
                        }
268
                        else {
269
#ifdef DEBUG_AUDIO_BUFFER
270
                                printf("AUDIO_BUFFER: cannot alloc space for decoded packet %d\n", pkt->stream_index);
271
#endif
272
                        }
273
                }
274
                else {
275
#ifdef DEBUG_AUDIO_BUFFER
276
                        printf("AUDIO_BUFFER: cannot decode packet %d\n", pkt->stream_index);
277
#endif
278
                }
279
                av_free(audio_bufQ);
280
        }
281
        else {
282
#ifdef DEBUG_AUDIO_BUFFER
283
                printf("AUDIO_BUFFER: cannot alloc decode buffer for packet %d\n", pkt->stream_index);
284
#endif
285
        }
286 d0819384 GiuseppeTropea
        return ret; //problems occurred
287 f126ff44 GiuseppeTropea
}
288
289
290 88fe20d0 GiuseppeTropea
//removes a packet from the list and returns the next
291
AVPacketList *remove_from_queue(PacketQueue *q, AVPacketList *p) {
292
        AVPacketList *retpk = p->next;
293
        q->nb_packets--;
294
        //adjust size here and not in the various cases of the dequeue
295
        q->size -= p->pkt.size;
296 e08af472 GiuseppeTropea
        if(&p->pkt)
297
                av_free_packet(&p->pkt);
298
        if(p)
299
                av_free(p);
300 88fe20d0 GiuseppeTropea
        return retpk;
301
}
302 f126ff44 GiuseppeTropea
303 88fe20d0 GiuseppeTropea
AVPacketList *seek_and_decode_packet_starting_from(AVPacketList *p, PacketQueue *q) {
304
        while(p) {
305
                        //check if audio packet has been already decoded
306
                        if(p->pkt.convergence_duration == 0) {
307
                                //not decoded yet, try to decode it
308
                                if( !decode_enqueued_audio_packet(&(p->pkt), q) ) {
309
                                        //it was not possible to decode this packet, return next one
310
                                        p = remove_from_queue(q, p);
311
                                }
312
                                else
313
                                        return p;
314
                        }
315
                        else
316
                                return p;
317
        }
318
        return NULL;
319
}
320
321
void update_queue_stats(PacketQueue *q, int packet_index) {
322
        //compute lost frame statistics
323
        if(q->last_frame_extracted > 0 && packet_index > q->last_frame_extracted) {
324
                q->total_lost_frames = q->total_lost_frames + packet_index - q->last_frame_extracted - 1;
325
#ifdef DEBUG_STATS
326
                printf("  STATS QUEUE stats: stidx %d last %d tot %d\n", packet_index, q->last_frame_extracted, q->total_lost_frames);
327
#endif
328
        }
329
}
330 f126ff44 GiuseppeTropea
331 34149271 GiuseppeTropea
int packet_queue_get(PacketQueue *q, AVPacket *pkt, short int av) {
332 1e69ae95 GiuseppeTropea
        //AVPacket tmp;
333 34149271 GiuseppeTropea
        AVPacketList *pkt1 = NULL;
334 1e69ae95 GiuseppeTropea
        int ret=-1;
335
        int SizeToCopy=0;
336
337 34149271 GiuseppeTropea
        SDL_LockMutex(q->mutex);
338
339 1e69ae95 GiuseppeTropea
#ifdef DEBUG_QUEUE
340 34149271 GiuseppeTropea
        printf("QUEUE: Get NPackets=%d Type=%d\n", q->nb_packets, q->queueType);
341 1e69ae95 GiuseppeTropea
#endif
342
343
        if((q->queueType==AUDIO && QueueFillingMode) || QueueStopped)
344
        {
345 34149271 GiuseppeTropea
                SDL_UnlockMutex(q->mutex);
346 1e69ae95 GiuseppeTropea
                return -1;
347
        }
348
349 88fe20d0 GiuseppeTropea
        if(av==1) { //somebody requested an audio packet, q is the audio queue
350
                //try to dequeue the first packet of the audio queue
351
                pkt1 = seek_and_decode_packet_starting_from(q->first_pkt, q);
352
                if(pkt1) { //yes we have them!
353
                        if(pkt1->pkt.size-AudioQueueOffset > dimAudioQ) {
354
                                //one packet if enough to give us the requested number of bytes by the audio_callback
355 1e69ae95 GiuseppeTropea
#ifdef DEBUG_QUEUE
356 e810bf7b GiuseppeTropea
                                printf("  AV=1 and Extract from the same packet\n");
357 1e69ae95 GiuseppeTropea
#endif
358
                                pkt->size = dimAudioQ;
359
                                memcpy(pkt->data,pkt1->pkt.data+AudioQueueOffset,dimAudioQ);
360
                                pkt->dts = pkt1->pkt.dts;
361
                                pkt->pts = pkt1->pkt.pts;
362 e810bf7b GiuseppeTropea
                                pkt->stream_index = pkt1->pkt.stream_index;//1;
363 1e69ae95 GiuseppeTropea
                                pkt->flags = 1;
364
                                pkt->pos = -1;
365
                                pkt->convergence_duration = -1;
366 34149271 GiuseppeTropea
#ifdef DEBUG_QUEUE
367 88fe20d0 GiuseppeTropea
                                printf("   Adjust timestamps Old = %lld New = %lld\n", pkt1->pkt.dts, (int64_t)(pkt1->pkt.dts + deltaAudioQ + deltaAudioQError));
368 34149271 GiuseppeTropea
#endif
369
                                int64_t Olddts=pkt1->pkt.dts;
370
                                pkt1->pkt.dts += deltaAudioQ + deltaAudioQError;
371
                                pkt1->pkt.pts += deltaAudioQ + deltaAudioQError;
372
                                deltaAudioQError=(float)Olddts + deltaAudioQ + deltaAudioQError - (float)pkt1->pkt.dts;
373 1e69ae95 GiuseppeTropea
                                AudioQueueOffset += dimAudioQ;
374
#ifdef DEBUG_QUEUE
375 34149271 GiuseppeTropea
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
376 1e69ae95 GiuseppeTropea
#endif
377 88fe20d0 GiuseppeTropea
                                //update overall state of queue
378
                                //size is diminished because we played some audio samples
379
                                //but packet is not removed since a portion has still to be played
380
                                //HINT ERRATA we had a size mismatch since size grows with the
381
                                //number of compressed bytes, and diminishes here with the number
382
                                //of raw uncompressed bytes, hence we update size during the
383
                                //real removes and not here anymore
384
                                //q->size -= dimAudioQ;
385
                                update_queue_stats(q, pkt->stream_index);
386 e810bf7b GiuseppeTropea
                                //update index of last frame extracted
387 f9cf0a8d GiuseppeTropea
                                q->last_frame_extracted = pkt->stream_index;
388 f126ff44 GiuseppeTropea
#ifdef DEBUG_AUDIO_BUFFER
389
                                printf("1: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
390
#endif
391 88fe20d0 GiuseppeTropea
                                ret = 1; //OK
392 1e69ae95 GiuseppeTropea
                        }
393
                        else {
394 88fe20d0 GiuseppeTropea
                                //we need bytes from two consecutive packets to satisfy the audio_callback
395 1e69ae95 GiuseppeTropea
#ifdef DEBUG_QUEUE
396 e810bf7b GiuseppeTropea
                                printf("  AV = 1 and Extract from 2 packets\n");
397 1e69ae95 GiuseppeTropea
#endif
398 88fe20d0 GiuseppeTropea
                                //check for a valid next packet since we will finish the current packet
399
                                //and also take some bytes from the next one
400
                                pkt1->next = seek_and_decode_packet_starting_from(pkt1->next, q);
401 f126ff44 GiuseppeTropea
                                if(pkt1->next) {
402 e810bf7b GiuseppeTropea
#ifdef DEBUG_QUEUE
403
                                        printf("   we have a next...\n");
404
#endif
405 1e69ae95 GiuseppeTropea
                                        pkt->size = dimAudioQ;
406
                                        pkt->dts = pkt1->pkt.dts;
407
                                        pkt->pts = pkt1->pkt.pts;
408 e810bf7b GiuseppeTropea
                                        pkt->stream_index = pkt1->pkt.stream_index;//1;
409 1e69ae95 GiuseppeTropea
                                        pkt->flags = 1;
410
                                        pkt->pos = -1;
411
                                        pkt->convergence_duration = -1;
412
                                        {
413
                                                SizeToCopy=pkt1->pkt.size-AudioQueueOffset;
414
#ifdef DEBUG_QUEUE
415 e810bf7b GiuseppeTropea
                                                printf("      SizeToCopy=%d\n",SizeToCopy);
416 1e69ae95 GiuseppeTropea
#endif
417 88fe20d0 GiuseppeTropea
                                                memcpy(pkt->data, pkt1->pkt.data+AudioQueueOffset, SizeToCopy);
418
                                                memcpy(pkt->data+SizeToCopy, pkt1->next->pkt.data, (dimAudioQ-SizeToCopy)*sizeof(uint8_t));
419 1e69ae95 GiuseppeTropea
                                        }
420 f126ff44 GiuseppeTropea
#ifdef DEBUG_AUDIO_BUFFER
421
                                        printf("2: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
422
#endif
423
                                }
424
#ifdef DEBUG_AUDIO_BUFFER
425
                                else {
426
                                        printf("2: NONEXT\n");
427 1e69ae95 GiuseppeTropea
                                }
428 f126ff44 GiuseppeTropea
#endif
429 88fe20d0 GiuseppeTropea
                                //HINT SEE before q->size -= SizeToCopy;
430
                                q->first_pkt = remove_from_queue(q, pkt1);
431 34149271 GiuseppeTropea
432 1e69ae95 GiuseppeTropea
                                // Adjust timestamps
433
                                pkt1 = q->first_pkt;
434 88fe20d0 GiuseppeTropea
                                if(pkt1) {
435 f126ff44 GiuseppeTropea
                                        int Offset=(dimAudioQ-SizeToCopy)*1000/(spec.freq*2*spec.channels);
436
                                        int64_t LastDts=pkt1->pkt.dts;
437
                                        pkt1->pkt.dts += Offset + deltaAudioQError;
438
                                        pkt1->pkt.pts += Offset + deltaAudioQError;
439
                                        deltaAudioQError = (float)LastDts + (float)Offset + deltaAudioQError - (float)pkt1->pkt.dts;
440 34149271 GiuseppeTropea
#ifdef DEBUG_QUEUE
441 f126ff44 GiuseppeTropea
                                        printf("   Adjust timestamps Old = %lld New = %lld\n", LastDts, pkt1->pkt.dts);
442 34149271 GiuseppeTropea
#endif
443 f126ff44 GiuseppeTropea
                                        AudioQueueOffset = dimAudioQ - SizeToCopy;
444 88fe20d0 GiuseppeTropea
                                        //SEE BEFORE HINT q->size -= AudioQueueOffset;
445 1e69ae95 GiuseppeTropea
                                        ret = 1;
446
                                }
447 88fe20d0 GiuseppeTropea
                                else {
448 1e69ae95 GiuseppeTropea
                                        AudioQueueOffset=0;
449 f126ff44 GiuseppeTropea
#ifdef DEBUG_AUDIO_BUFFER
450
                                        printf("0: idx %d    \taqo %d    \tstc %d    \taqe %f    \tpsz %d\n", pkt1->pkt.stream_index, AudioQueueOffset, SizeToCopy, deltaAudioQError, pkt1->pkt.size);
451
#endif
452 1e69ae95 GiuseppeTropea
                                }
453
#ifdef DEBUG_QUEUE
454 34149271 GiuseppeTropea
                                printf("   deltaAudioQError = %f\n",deltaAudioQError);
455 1e69ae95 GiuseppeTropea
#endif
456 88fe20d0 GiuseppeTropea
                                update_queue_stats(q, pkt->stream_index);
457 e810bf7b GiuseppeTropea
                                //update index of last frame extracted
458 f9cf0a8d GiuseppeTropea
                                q->last_frame_extracted = pkt->stream_index;
459 1e69ae95 GiuseppeTropea
                        }
460
                }
461 88fe20d0 GiuseppeTropea
        }
462
        else { //somebody requested a video packet, q is the video queue
463
                pkt1 = q->first_pkt;
464
                if(pkt1) {
465 e810bf7b GiuseppeTropea
#ifdef DEBUG_QUEUE
466 34149271 GiuseppeTropea
                        printf("  AV not 1\n");
467 e810bf7b GiuseppeTropea
#endif
468 1e69ae95 GiuseppeTropea
                        pkt->size = pkt1->pkt.size;
469
                        pkt->dts = pkt1->pkt.dts;
470
                        pkt->pts = pkt1->pkt.pts;
471
                        pkt->stream_index = pkt1->pkt.stream_index;
472
                        pkt->flags = pkt1->pkt.flags;
473
                        pkt->pos = pkt1->pkt.pos;
474
                        pkt->convergence_duration = pkt1->pkt.convergence_duration;
475
                        //*pkt = pkt1->pkt;
476 88fe20d0 GiuseppeTropea
                        memcpy(pkt->data, pkt1->pkt.data, pkt1->pkt.size);
477
478
                        //HINT SEE BEFORE q->size -= pkt1->pkt.size;
479
                        q->first_pkt = remove_from_queue(q, pkt1);
480
481 1e69ae95 GiuseppeTropea
                        ret = 1;
482 88fe20d0 GiuseppeTropea
                        update_queue_stats(q, pkt->stream_index);
483 e810bf7b GiuseppeTropea
                        //update index of last frame extracted
484 f9cf0a8d GiuseppeTropea
                        q->last_frame_extracted = pkt->stream_index;
485 1e69ae95 GiuseppeTropea
                }
486 e810bf7b GiuseppeTropea
#ifdef DEBUG_QUEUE
487 88fe20d0 GiuseppeTropea
                else {
488
                        printf("  VIDEO pk1 NULL!!!!\n");
489
                }
490 e810bf7b GiuseppeTropea
#endif
491 88fe20d0 GiuseppeTropea
        }
492 e810bf7b GiuseppeTropea
493
        if(q->nb_packets==0 && q->queueType==AUDIO) {
494 1e69ae95 GiuseppeTropea
                QueueFillingMode=1;
495 e810bf7b GiuseppeTropea
#ifdef DEBUG_QUEUE
496 34149271 GiuseppeTropea
                printf("QUEUE: Get FillingMode ON\n");
497 e810bf7b GiuseppeTropea
#endif
498
        }
499
#ifdef DEBUG_QUEUE
500 34149271 GiuseppeTropea
        printf("QUEUE: Get LastFrameExtracted = %d\n",q->last_frame_extracted);
501
        printf("QUEUE: Get Tot lost frames = %d\n",q->total_lost_frames);
502 e810bf7b GiuseppeTropea
#endif
503 1e69ae95 GiuseppeTropea
504
        SDL_UnlockMutex(q->mutex);
505
        return ret;
506
}
507
508
509
int audio_decode_frame(uint8_t *audio_buf, int buf_size) {
510
        //struct timeval now;
511
        int audio_pkt_size = 0;
512
        long long Now;
513
        short int DecodeAudio=0, SkipAudio=0;
514
        //int len1, data_size;
515
516
        //gettimeofday(&now,NULL);
517
        //Now = (now.tv_sec)*1000+now.tv_usec/1000;
518
        Now=(long long)SDL_GetTicks();
519
520
        if(QueueFillingMode || QueueStopped)
521
        {
522 34149271 GiuseppeTropea
                //SDL_LockMutex(timing_mutex);
523 1e69ae95 GiuseppeTropea
                FirstTimeAudio=1;
524 f9cf0a8d GiuseppeTropea
                FirstTime = 1;
525 34149271 GiuseppeTropea
                //SDL_UnlockMutex(timing_mutex);
526 1e69ae95 GiuseppeTropea
                return -1;
527
        }
528
529 f9cf0a8d GiuseppeTropea
        if((FirstTime==1 || FirstTimeAudio==1) && audioq.size>0) {
530 1e69ae95 GiuseppeTropea
                if(audioq.first_pkt->pkt.pts>0)
531
                {
532 34149271 GiuseppeTropea
                        //SDL_LockMutex(timing_mutex);
533 f9cf0a8d GiuseppeTropea
                        DeltaTime=Now-(long long)(audioq.first_pkt->pkt.pts);
534 1e69ae95 GiuseppeTropea
                        FirstTimeAudio = 0;
535 f9cf0a8d GiuseppeTropea
                        FirstTime = 0;
536 34149271 GiuseppeTropea
                        //SDL_UnlockMutex(timing_mutex);
537 1e69ae95 GiuseppeTropea
#ifdef DEBUG_AUDIO 
538 34149271 GiuseppeTropea
                         printf("AUDIO: audio_decode_frame - DeltaTimeAudio=%lld\n",DeltaTime);
539 1e69ae95 GiuseppeTropea
#endif
540
                }
541
        }
542
543
#ifdef DEBUG_AUDIO 
544
        if(audioq.first_pkt)
545
        {
546 34149271 GiuseppeTropea
                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);
547
                printf("AUDIO: QueueLen=%d ",(int)audioq.nb_packets);
548
                printf("AUDIO: QueueSize=%d\n",(int)audioq.size);
549 1e69ae95 GiuseppeTropea
        }
550
        else
551 34149271 GiuseppeTropea
                printf("AUDIO: audio_decode_frame - Empty queue\n");
552 1e69ae95 GiuseppeTropea
#endif
553
554
555
        if(audioq.nb_packets>0) {
556 f9cf0a8d GiuseppeTropea
                if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
557 1e69ae95 GiuseppeTropea
                        SkipAudio = 1;
558
                        DecodeAudio = 0;
559
                }
560 f9cf0a8d GiuseppeTropea
                else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
561
                        (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
562 1e69ae95 GiuseppeTropea
                                SkipAudio = 0;
563
                                DecodeAudio = 1;
564
                }
565
        }
566
                
567
        while(SkipAudio==1 && audioq.size>0) {
568
                SkipAudio = 0;
569
#ifdef DEBUG_AUDIO
570 34149271 GiuseppeTropea
                 printf("AUDIO: skipaudio: queue size=%d\n",audioq.size);
571 1e69ae95 GiuseppeTropea
#endif
572
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
573
                        return -1;
574
                }
575
                if(audioq.first_pkt)
576
                {
577 f9cf0a8d GiuseppeTropea
                        if((long long)audioq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
578 1e69ae95 GiuseppeTropea
                                SkipAudio = 1;
579
                                DecodeAudio = 0;
580
                        }
581 f9cf0a8d GiuseppeTropea
                        else if((long long)audioq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
582
                                (long long)audioq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
583 1e69ae95 GiuseppeTropea
                                        SkipAudio = 0;
584
                                        DecodeAudio = 1;
585
                        }
586
                }
587
        }
588
        if(DecodeAudio==1) {
589
                if(packet_queue_get(&audioq,&AudioPkt,1) < 0) {
590
                        return -1;
591
                }
592
                memcpy(audio_buf,AudioPkt.data,AudioPkt.size);
593
                audio_pkt_size = AudioPkt.size;
594
#ifdef DEBUG_AUDIO
595 34149271 GiuseppeTropea
                 printf("AUDIO: Decode audio\n");
596 1e69ae95 GiuseppeTropea
#endif
597
        }
598
599
        return audio_pkt_size;
600
}
601
602
603
int video_callback(void *valthread) {
604
        //AVPacket pktvideo;
605
        AVCodecContext  *pCodecCtx;
606 34149271 GiuseppeTropea
        AVCodec         *pCodec;
607
        AVFrame         *pFrame;
608
        AVPacket        packet;
609
        int frameFinished;
610
        int countexit;
611 1e69ae95 GiuseppeTropea
        AVPicture pict;
612
        //FILE *frecon;
613
        SDL_Event event;
614
        long long Now;
615
        short int SkipVideo, DecodeVideo;
616
617
        //double frame_rate = 0.0,time_between_frames=0.0;
618
        //struct timeval now;
619
620
        //int wait_for_sync = 1;
621
        ThreadVal *tval;
622
        tval = (ThreadVal *)valthread;
623
624
        //frame_rate = tval->framerate;
625
        //time_between_frames = 1.e6 / frame_rate;
626
        //gettimeofday(&time_now,0);
627
628
        //frecon = fopen("recondechunk.mpg","wb");
629
630
        pCodecCtx=avcodec_alloc_context();
631 34149271 GiuseppeTropea
        pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
632 e810bf7b GiuseppeTropea
#ifdef H264_VIDEO_ENCODER
633 34149271 GiuseppeTropea
        pCodecCtx->codec_id  = CODEC_ID_H264;
634
        pCodecCtx->me_range = 16;
635
        pCodecCtx->max_qdiff = 4;
636
        pCodecCtx->qmin = 10;
637
        pCodecCtx->qmax = 51;
638
        pCodecCtx->qcompress = 0.6;
639 e810bf7b GiuseppeTropea
#else
640 34149271 GiuseppeTropea
        pCodecCtx->codec_id  = CODEC_ID_MPEG4;
641 e810bf7b GiuseppeTropea
#endif
642 34149271 GiuseppeTropea
        //pCodecCtx->bit_rate = 400000;
643
        // resolution must be a multiple of two
644
        pCodecCtx->width = tval->width;//176;//352;
645
        pCodecCtx->height = tval->height;//144;//288;
646
        // frames per second
647
        //pCodecCtx->time_base = (AVRational){1,25};
648
        //pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
649
        //pCodecCtx->max_b_frames=1;
650
        pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
651
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
652
653
        if(pCodec==NULL) {
654
                fprintf(stderr, "Unsupported codec!\n");
655
                return -1; // Codec not found
656
        }
657
        if(avcodec_open(pCodecCtx, pCodec) < 0) {
658
                fprintf(stderr, "could not open codec\n");
659
                return -1; // Could not open codec
660
        }
661 1e69ae95 GiuseppeTropea
        pFrame=avcodec_alloc_frame();
662 34149271 GiuseppeTropea
        if(pFrame==NULL) {
663
                printf("Memory error!!!\n");
664
                return -1;
665
        }
666 1e69ae95 GiuseppeTropea
667
        while(!quit) {
668
                if(QueueFillingMode || QueueStopped)
669
                {
670 34149271 GiuseppeTropea
                        //SDL_LockMutex(timing_mutex);
671 f9cf0a8d GiuseppeTropea
                        FirstTime = 1;
672 34149271 GiuseppeTropea
                        //SDL_UnlockMutex(timing_mutex);
673 1e69ae95 GiuseppeTropea
                        usleep(5000);
674
                        continue;
675
                }
676
677
                DecodeVideo = 0;
678
                SkipVideo = 0;
679
                Now=(long long)SDL_GetTicks();
680 f9cf0a8d GiuseppeTropea
                if(FirstTime==1 && videoq.size>0) {
681 1e69ae95 GiuseppeTropea
                        if(videoq.first_pkt->pkt.pts>0)
682
                        {
683 34149271 GiuseppeTropea
                                //SDL_LockMutex(timing_mutex);
684 f9cf0a8d GiuseppeTropea
                                DeltaTime=Now-(long long)videoq.first_pkt->pkt.pts;
685
                                FirstTime = 0;
686 34149271 GiuseppeTropea
                                //SDL_UnlockMutex(timing_mutex);
687 1e69ae95 GiuseppeTropea
                        }
688
#ifdef DEBUG_VIDEO 
689 34149271 GiuseppeTropea
                         printf("VIDEO: VideoCallback - DeltaTimeAudio=%lld\n",DeltaTime);
690 1e69ae95 GiuseppeTropea
#endif
691
                }
692
693
#ifdef DEBUG_VIDEO 
694
                if(videoq.first_pkt)
695
                {
696 34149271 GiuseppeTropea
                        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);
697 88fe20d0 GiuseppeTropea
                        printf("VIDEO: Index=%d ", (int)videoq.first_pkt->pkt.stream_index);
698
                        printf("VIDEO: QueueLen=%d ", (int)videoq.nb_packets);
699
                        printf("VIDEO: QueueSize=%d\n", (int)videoq.size);
700 1e69ae95 GiuseppeTropea
                }
701
                else
702 34149271 GiuseppeTropea
                        printf("VIDEO: VideoCallback - Empty queue\n");
703 1e69ae95 GiuseppeTropea
#endif
704
705
                if(videoq.nb_packets>0) {
706 f9cf0a8d GiuseppeTropea
                        if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)<Now-(long long)MAX_TOLLERANCE) {
707 1e69ae95 GiuseppeTropea
                                SkipVideo = 1;
708
                                DecodeVideo = 0;
709
                        }
710
                        else 
711 f9cf0a8d GiuseppeTropea
                                if(((long long)videoq.first_pkt->pkt.pts+DeltaTime)>=Now-(long long)MAX_TOLLERANCE &&
712
                                   ((long long)videoq.first_pkt->pkt.pts+DeltaTime)<=Now+(long long)MAX_TOLLERANCE) {
713 1e69ae95 GiuseppeTropea
                                        SkipVideo = 0;
714
                                        DecodeVideo = 1;
715
                                }
716
                }
717 f9cf0a8d GiuseppeTropea
#ifdef DEBUG_VIDEO
718 34149271 GiuseppeTropea
                printf("VIDEO: skipvideo:%d decodevideo:%d\n",SkipVideo,DecodeVideo);
719 f9cf0a8d GiuseppeTropea
#endif
720 1e69ae95 GiuseppeTropea
721
                while(SkipVideo==1 && videoq.size>0) {
722
                        SkipVideo = 0;
723
#ifdef DEBUG_VIDEO 
724 34149271 GiuseppeTropea
                         printf("VIDEO: Skip Video\n");
725 1e69ae95 GiuseppeTropea
#endif
726
                        if(packet_queue_get(&videoq,&VideoPkt,0) < 0) {
727
                                break;
728
                        }
729
                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
730
                        if(videoq.first_pkt)
731
                        {
732 f9cf0a8d GiuseppeTropea
                                if((long long)videoq.first_pkt->pkt.pts+DeltaTime<Now-(long long)MAX_TOLLERANCE) {
733 1e69ae95 GiuseppeTropea
                                        SkipVideo = 1;
734
                                        DecodeVideo = 0;
735
                                }
736 f9cf0a8d GiuseppeTropea
                                else if((long long)videoq.first_pkt->pkt.pts+DeltaTime>=Now-(long long)MAX_TOLLERANCE &&
737 34149271 GiuseppeTropea
                                                                (long long)videoq.first_pkt->pkt.pts+DeltaTime<=Now+(long long)MAX_TOLLERANCE) {
738 1e69ae95 GiuseppeTropea
                                        SkipVideo = 0;
739
                                        DecodeVideo = 1;
740
                                }
741
                        }
742
                }
743
                
744
                if(DecodeVideo==1) {
745
                        if(packet_queue_get(&videoq,&VideoPkt,0) > 0) {
746
747
#ifdef DEBUG_VIDEO
748 34149271 GiuseppeTropea
                                printf("VIDEO: Decode video FrameTime=%lld Now=%lld\n",(long long)VideoPkt.pts+DeltaTime,Now);
749 1e69ae95 GiuseppeTropea
#endif
750
751
                                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &VideoPkt);
752
753 e810bf7b GiuseppeTropea
                                if(frameFinished) { // it must be true all the time else error
754
#ifdef DEBUG_VIDEO
755 34149271 GiuseppeTropea
                                        printf("VIDEO: FrameFinished\n");
756 e810bf7b GiuseppeTropea
#endif
757 1e69ae95 GiuseppeTropea
                                        //SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height, cont++);
758
                                        //fwrite(pktvideo.data, 1, pktvideo.size, frecon);
759
760 34149271 GiuseppeTropea
                                        // Lock SDL_yuv_overlay
761
                                        if(SDL_MUSTLOCK(screen)) {
762 e810bf7b GiuseppeTropea
763 34149271 GiuseppeTropea
                                                if(SDL_LockSurface(screen) < 0) {
764
                                                        continue;
765
                                                }
766
                                        }
767 1e69ae95 GiuseppeTropea
768 34149271 GiuseppeTropea
                                        if(SDL_LockYUVOverlay(yuv_overlay) < 0) {
769
                                                if(SDL_MUSTLOCK(screen)) {
770
                                                        SDL_UnlockSurface(screen);
771
                                                }
772
                                                continue;
773
                                        }
774
                                        pict.data[0] = yuv_overlay->pixels[0];
775
                                        pict.data[1] = yuv_overlay->pixels[2];
776
                                        pict.data[2] = yuv_overlay->pixels[1];
777
778
                                        pict.linesize[0] = yuv_overlay->pitches[0];
779
                                        pict.linesize[1] = yuv_overlay->pitches[2];
780
                                        pict.linesize[2] = yuv_overlay->pitches[1];
781
                                        if(img_convert_ctx == NULL) {
782
                                                img_convert_ctx = sws_getContext(tval->width, tval->height, PIX_FMT_YUV420P, tval->width, tval->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
783
                                                if(img_convert_ctx == NULL) {
784
                                                        fprintf(stderr, "Cannot initialize the conversion context!\n");
785
                                exit(1);
786
                                                }
787
                                        }
788
                                        // let's draw the data (*yuv[3]) on a SDL screen (*screen)
789
                                        sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, tval->height, pict.data, pict.linesize);
790
                                        SDL_UnlockYUVOverlay(yuv_overlay);
791
                                        // Show, baby, show!
792
                                        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
793
                                        if(SDL_MUSTLOCK(screen)) {
794
                                                SDL_UnlockSurface(screen);
795
                                        }
796
                                } //if FrameFinished
797
                        } // if packet_queue_get
798
                } //if DecodeVideo=1
799 1e69ae95 GiuseppeTropea
800
                usleep(5000);
801
        }
802
        av_free(pCodecCtx);
803
        //fclose(frecon);
804
#ifdef DEBUG_VIDEO
805 34149271 GiuseppeTropea
         printf("VIDEO: video callback end\n");
806 1e69ae95 GiuseppeTropea
#endif
807
        return 1;
808
}
809
810
811
void audio_callback(void *userdata, Uint8 *stream, int len) {
812
813
        //AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
814
        int audio_size;
815
816
        static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
817
818
        audio_size = audio_decode_frame(audio_buf, sizeof(audio_buf));
819
        if(audio_size != len) {
820
                memset(stream, 0, len);
821
        } else {
822
                memcpy(stream, (uint8_t *)audio_buf, len);
823
        }
824
}
825
826
void ShowBMP(char *file, SDL_Surface *screen, int x, int y) {
827
        SDL_Surface *image;
828
        SDL_Rect dest;
829
830
        /* Load a BMP file on a surface */
831
        image = SDL_LoadBMP(file);
832
        if ( image == NULL ) {
833
                fprintf(stderr, "Error loading %s: %s\n", file, SDL_GetError());
834
                return;
835
        }
836
837
        /* Copy on the screen surface 
838
        surface should be blocked now.
839
        */
840
        dest.x = x;
841
        dest.y = y;
842
        dest.w = image->w;
843
        dest.h = image->h;
844
        SDL_BlitSurface(image, NULL, screen, &dest);
845
846
        /* Update the screen area just changed */
847
        SDL_UpdateRects(screen, 1, &dest);
848
}
849
850
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
851
        FILE *pFile;
852
        char szFilename[32];
853
        int  y;
854
  
855 34149271 GiuseppeTropea
         // Open file
856 1e69ae95 GiuseppeTropea
        sprintf(szFilename, "frame%d.ppm", iFrame);
857 34149271 GiuseppeTropea
        pFile=fopen(szFilename, "wb");
858
        if(pFile==NULL)
859
                return;
860 1e69ae95 GiuseppeTropea
  
861 34149271 GiuseppeTropea
        // Write header
862
        fprintf(pFile, "P5\n%d %d\n255\n", width, height);
863 1e69ae95 GiuseppeTropea
  
864 34149271 GiuseppeTropea
        // Write pixel data
865
        for(y=0; y<height; y++)
866
                  fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile);
867 1e69ae95 GiuseppeTropea
  
868 34149271 GiuseppeTropea
        // Close file
869
        fclose(pFile);
870 1e69ae95 GiuseppeTropea
}
871
872 34149271 GiuseppeTropea
void sigint_handler (int signal) {
873
        printf("Caught SIGINT, exiting...");
874
        got_sigint = 1;
875 1e69ae95 GiuseppeTropea
}
876
877 f126ff44 GiuseppeTropea
void ProcessKeys() {
878 1e69ae95 GiuseppeTropea
        static Uint32 LastTime=0;
879
        static int LastKey=-1;
880
881
        Uint32 Now=SDL_GetTicks();
882
        Uint8* keystate=SDL_GetKeyState(NULL);
883
        if(keystate[SDLK_SPACE] &&
884
          (LastKey!=SDLK_SPACE || (LastKey==SDLK_SPACE && (Now-LastTime>1000))))
885
        {
886
                LastKey=SDLK_SPACE;
887
                LastTime=Now;
888
                QueueStopped=!QueueStopped;
889
        }
890
        if(keystate[SDLK_ESCAPE] &&
891
          (LastKey!=SDLK_ESCAPE || (LastKey==SDLK_ESCAPE && (Now-LastTime>1000))))
892
        {
893
                LastKey=SDLK_ESCAPE;
894
                LastTime=Now;
895
                quit=1;
896
        }
897
        /*if(keystate[SDLK_f] &&
898
          (LastKey!=SDLK_f || (LastKey==SDLK_f && (Now-LastTime>1000))))
899
        {
900
                LastKey=SDLK_f;
901
                LastTime=Now;
902
                SDL_WM_ToggleFullScreen(NULL);
903
        }*/
904
}
905
906
int main(int argc, char *argv[]) {
907 f9cf0a8d GiuseppeTropea
        int i, j, videoStream,outbuf_size,out_size,out_size_audio,seq_current_chunk = 0,audioStream;
908 1e69ae95 GiuseppeTropea
        int len1, data_size, stime,cont=0;
909
        int frameFinished, len_audio;
910
        int numBytes,outbuf_audio_size,audio_size;
911
912 e810bf7b GiuseppeTropea
        int y;
913 1e69ae95 GiuseppeTropea
        
914
        uint8_t *outbuf,*outbuf_audio;
915
        uint8_t *outbuf_audi_audio;
916
        
917
        AVFormatContext *pFormatCtx;
918
919
        AVCodec         *pCodec,*aCodec;
920
        AVFrame         *pFrame; 
921
922
        AVPicture pict;
923
        SDL_Thread *video_thread;//exit_thread,*exit_thread2;
924
        SDL_Event event;
925 f126ff44 GiuseppeTropea
        SDL_AudioSpec wanted_spec;
926 1e69ae95 GiuseppeTropea
        
927 e810bf7b GiuseppeTropea
        struct MHD_Daemon *daemon = NULL;        
928
929 1e69ae95 GiuseppeTropea
        char buf[1024],outfile[1024], basereadfile[1024],readfile[1024];
930
        FILE *fp;        
931 f9cf0a8d GiuseppeTropea
        int width,height,asample_rate,achannels;
932 1e69ae95 GiuseppeTropea
933
        ThreadVal *tval;
934
        tval = (ThreadVal *)malloc(sizeof(ThreadVal));
935
                
936 af501115 GiuseppeTropea
        if(argc<6) {
937
                printf("chunker_player width height audio_sample_rate audio_channels queue_thresh\n");
938 1e69ae95 GiuseppeTropea
                exit(1);
939
        }
940
        sscanf(argv[1],"%d",&width);
941
        sscanf(argv[2],"%d",&height);
942 f9cf0a8d GiuseppeTropea
        sscanf(argv[3],"%d",&asample_rate);
943
        sscanf(argv[4],"%d",&achannels);
944 af501115 GiuseppeTropea
        sscanf(argv[5],"%d",&queue_filling_threshold);
945 1e69ae95 GiuseppeTropea
        tval->width = width;
946
        tval->height = height;
947
        
948
        // Register all formats and codecs
949
950
        av_register_all();
951
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
952
                fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
953
                return -1;
954
        }
955
956
        aCodecCtx = avcodec_alloc_context();
957 f9cf0a8d GiuseppeTropea
        //aCodecCtx->bit_rate = 64000;
958
        aCodecCtx->sample_rate = asample_rate;
959
        aCodecCtx->channels = achannels;
960 e810bf7b GiuseppeTropea
#ifdef MP3_AUDIO_ENCODER
961 f9cf0a8d GiuseppeTropea
        aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
962 e810bf7b GiuseppeTropea
#else
963
        aCodec = avcodec_find_decoder(CODEC_ID_MP2);
964
#endif
965
        printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
966 1e69ae95 GiuseppeTropea
        if(!aCodec) {
967
                printf("Codec not found!\n");
968
                return -1;
969
        }
970
        if(avcodec_open(aCodecCtx, aCodec)<0) {
971
                fprintf(stderr, "could not open codec\n");
972
                return -1; // Could not open codec
973
        }
974 e810bf7b GiuseppeTropea
        printf("using audio Codecid: %d ",aCodecCtx->codec_id);
975
        printf("samplerate: %d ",aCodecCtx->sample_rate);
976
        printf("channels: %d\n",aCodecCtx->channels);
977 1e69ae95 GiuseppeTropea
        wanted_spec.freq = aCodecCtx->sample_rate;
978
        wanted_spec.format = AUDIO_S16SYS;
979
        wanted_spec.channels = aCodecCtx->channels;
980
        wanted_spec.silence = 0;
981
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
982
        wanted_spec.callback = audio_callback;
983
        wanted_spec.userdata = aCodecCtx;
984
        if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
985
                fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
986
                return -1;
987
        }
988
        dimAudioQ = spec.size;
989
        deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
990
991 34149271 GiuseppeTropea
#ifdef DEBUG_AUDIO
992 1e69ae95 GiuseppeTropea
        printf("freq:%d\n",spec.freq);
993
        printf("format:%d\n",spec.format);
994
        printf("channels:%d\n",spec.channels);
995
        printf("silence:%d\n",spec.silence);
996
        printf("samples:%d\n",spec.samples);
997
        printf("size:%d\n",spec.size);
998 34149271 GiuseppeTropea
        printf("deltaAudioQ: %f\n",deltaAudioQ);
999
#endif
1000 1e69ae95 GiuseppeTropea
1001
        pFrame=avcodec_alloc_frame();
1002
        if(pFrame==NULL) {
1003
                printf("Memory error!!!\n");
1004
                return -1;
1005
        }
1006
        outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1007
1008 34149271 GiuseppeTropea
        packet_queue_init(&audioq, AUDIO);
1009
        packet_queue_init(&videoq, VIDEO);
1010 1e69ae95 GiuseppeTropea
        SDL_WM_SetCaption("Filling buffer...", NULL);
1011
        // Make a screen to put our video
1012
#ifndef __DARWIN__
1013
        screen = SDL_SetVideoMode(width, height, 0, 0);
1014
#else
1015
        screen = SDL_SetVideoMode(width, height, 24, 0);
1016
#endif
1017
        if(!screen) {
1018
                fprintf(stderr, "SDL: could not set video mode - exiting\n");
1019
                exit(1);
1020
        }
1021
        yuv_overlay = SDL_CreateYUVOverlay(width, height,SDL_YV12_OVERLAY, screen);
1022
1023
        if ( yuv_overlay == NULL ) {
1024
                fprintf(stderr,"SDL: Couldn't create SDL_yuv_overlay: %s", SDL_GetError());
1025
                exit(1);
1026
        }
1027
1028
        if ( yuv_overlay->hw_overlay )
1029
                fprintf(stderr,"SDL: Using hardware overlay.");
1030
1031
        rect.x = 0;
1032
        rect.y = 0;
1033
        rect.w = width;
1034
        rect.h = height;
1035
1036
        SDL_DisplayYUVOverlay(yuv_overlay, &rect);
1037
1038
        //signal (SIGINT, sigint_handler);
1039
1040
        // Init audio and video buffers
1041
        av_init_packet(&AudioPkt);
1042
        av_init_packet(&VideoPkt);
1043
        AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1044
        if(!AudioPkt.data) return 0;
1045
        VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
1046
        if(!VideoPkt.data) return 0;
1047
        
1048
        SDL_PauseAudio(0);
1049
        video_thread = SDL_CreateThread(video_callback,tval);
1050 34149271 GiuseppeTropea
        //timing_mutex = SDL_CreateMutex();
1051 1e69ae95 GiuseppeTropea
1052
        //SDL_WaitThread(exit_thread2,NULL);
1053
1054 e810bf7b GiuseppeTropea
        daemon = initChunkPuller();
1055 1e69ae95 GiuseppeTropea
1056
        // Wait for user input
1057 f126ff44 GiuseppeTropea
        while(!quit) {
1058 34149271 GiuseppeTropea
                if(QueueFillingMode) {
1059 1e69ae95 GiuseppeTropea
                        SDL_WM_SetCaption("Filling buffer...", NULL);
1060 34149271 GiuseppeTropea
1061
                        if(audioq.nb_packets==0 && audioq.last_frame_extracted>0) {        // video ended therefore init queues
1062
#ifdef DEBUG_QUEUE
1063
                                printf("QUEUE: MAIN SHOULD RESET\n");
1064
#endif
1065
                                packet_queue_reset(&audioq, AUDIO);
1066
                                packet_queue_reset(&videoq, VIDEO);
1067
                        }
1068
1069
#ifdef DEBUG_QUEUE
1070 f126ff44 GiuseppeTropea
                        //printf("QUEUE: MAIN audio:%d video:%d audiolastframe:%d videolastframe:%d\n", audioq.nb_packets, videoq.nb_packets, audioq.last_frame_extracted, videoq.last_frame_extracted);
1071 34149271 GiuseppeTropea
#endif
1072
                }
1073 1e69ae95 GiuseppeTropea
                else
1074
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
1075 34149271 GiuseppeTropea
1076 f126ff44 GiuseppeTropea
                //listen for key and mouse
1077
                while(SDL_PollEvent(&event)) {
1078
                                switch(event.type) {
1079
                                        case SDL_QUIT:
1080
                                                //exit(0);
1081
                                                quit=1;
1082
                                        break;
1083
                                }
1084
                                ProcessKeys();
1085 1e69ae95 GiuseppeTropea
                }
1086 34149271 GiuseppeTropea
                usleep(120000);
1087 1e69ae95 GiuseppeTropea
        }
1088 f9cf0a8d GiuseppeTropea
1089 f126ff44 GiuseppeTropea
        //TERMINATE
1090
        // Stop audio&video playback
1091 1e69ae95 GiuseppeTropea
        SDL_WaitThread(video_thread,NULL);
1092
        SDL_PauseAudio(1);
1093
        SDL_CloseAudio();
1094 34149271 GiuseppeTropea
        //SDL_DestroyMutex(timing_mutex);
1095 26379a77 GiuseppeTropea
        SDL_Quit();
1096 1e69ae95 GiuseppeTropea
        av_free(aCodecCtx);
1097
        free(AudioPkt.data);
1098
        free(VideoPkt.data);
1099 34149271 GiuseppeTropea
        free(outbuf_audio);
1100 e810bf7b GiuseppeTropea
        finalizeChunkPuller(daemon);
1101 1e69ae95 GiuseppeTropea
        return 0;
1102
}
1103
1104
1105
1106
int enqueueBlock(const uint8_t *block, const int block_size) {
1107 8b52d5cf GiuseppeTropea
        Chunk *gchunk = NULL;
1108
        ExternalChunk *echunk = NULL;
1109 e08af472 GiuseppeTropea
        int decoded_size = -1;
1110 1e69ae95 GiuseppeTropea
        uint8_t *tempdata, *buffer;
1111 34149271 GiuseppeTropea
        int i, j;
1112 8b52d5cf GiuseppeTropea
        Frame *frame = NULL;
1113 1e69ae95 GiuseppeTropea
        AVPacket packet, packetaudio;
1114
1115 34149271 GiuseppeTropea
        //uint8_t *video_bufQ = NULL;
1116 e810bf7b GiuseppeTropea
        uint16_t *audio_bufQ = NULL;
1117
        //uint8_t audio_bufQ[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
1118 34149271 GiuseppeTropea
        int16_t *dataQ = NULL;
1119 1e69ae95 GiuseppeTropea
        int data_sizeQ;
1120
        int lenQ;
1121 8b52d5cf GiuseppeTropea
        //the frame.h gets encoded into 5 slots of 32bits (3 ints plus 2 more for the timeval struct
1122
        static int sizeFrameHeader = 5*sizeof(int32_t);
1123 e08af472 GiuseppeTropea
        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;
1124 8b52d5cf GiuseppeTropea
1125 e810bf7b GiuseppeTropea
        audio_bufQ = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
1126 1e69ae95 GiuseppeTropea
        gchunk = (Chunk *)malloc(sizeof(Chunk));
1127
        if(!gchunk) {
1128 e810bf7b GiuseppeTropea
                printf("Memory error in gchunk!\n");
1129 1e69ae95 GiuseppeTropea
                return PLAYER_FAIL_RETURN;
1130
        }
1131
1132 e08af472 GiuseppeTropea
        decoded_size = decodeChunk(gchunk, block, block_size);
1133
#ifdef DEBUG_CHUNKER
1134
        printf("CHUNKER: enqueueBlock: decoded_size %d target size %d\n", decoded_size, GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size);
1135
#endif
1136
  if(decoded_size < 0 || decoded_size != GRAPES_ENCODED_CHUNK_HEADER_SIZE + ExternalChunk_header_size + gchunk->size) {
1137
                //HINT here i should differentiate between various return values of the decode
1138
                //in order to free what has been allocated there
1139
                printf("chunk probably corrupted!\n");
1140
                return PLAYER_FAIL_RETURN;
1141
        }
1142 1e69ae95 GiuseppeTropea
1143
        echunk = grapesChunkToExternalChunk(gchunk);
1144 34149271 GiuseppeTropea
        if(echunk == NULL) {
1145 e810bf7b GiuseppeTropea
                printf("Memory error in echunk!\n");
1146 34149271 GiuseppeTropea
                free(gchunk->attributes);
1147
                free(gchunk->data);
1148
                free(gchunk);
1149 e810bf7b GiuseppeTropea
                return PLAYER_FAIL_RETURN;
1150 34149271 GiuseppeTropea
        }
1151
        free(gchunk->attributes);
1152
        free(gchunk);
1153 1e69ae95 GiuseppeTropea
1154
        frame = (Frame *)malloc(sizeof(Frame));
1155
        if(!frame) {
1156
                printf("Memory error!\n");
1157
                return -1;
1158
        }
1159
1160 8b52d5cf GiuseppeTropea
        tempdata = echunk->data; //let it point to first frame of payload
1161 34149271 GiuseppeTropea
        j=echunk->payload_len;
1162
        while(j>0 && !quit) {
1163
                //usleep(30000);
1164 8b52d5cf GiuseppeTropea
/*
1165 bd209760 GiuseppeTropea
                frame->number = *((int32_t *)tempdata);
1166
                tempdata+=sizeof(int32_t);
1167 34149271 GiuseppeTropea
                frame->timestamp = *((struct timeval *)tempdata);
1168
                tempdata += sizeof(struct timeval);
1169 bd209760 GiuseppeTropea
                frame->size = *((int32_t *)tempdata);
1170
                tempdata+=sizeof(int32_t);
1171
                frame->type = *((int32_t *)tempdata);
1172
                tempdata+=sizeof(int32_t);
1173 8b52d5cf GiuseppeTropea
*/
1174
                frame->number = bit32_encoded_pull(tempdata);
1175
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1176
                frame->timestamp.tv_sec = bit32_encoded_pull(tempdata);
1177
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1178
                frame->timestamp.tv_usec = bit32_encoded_pull(tempdata);
1179
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1180
                frame->size = bit32_encoded_pull(tempdata);
1181
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1182
                frame->type = bit32_encoded_pull(tempdata);
1183
                tempdata += CHUNK_TRANSCODING_INT_SIZE;
1184 34149271 GiuseppeTropea
1185
                buffer = tempdata; // here coded frame information
1186 8b52d5cf GiuseppeTropea
                tempdata += frame->size; //let it point to the next frame
1187 34149271 GiuseppeTropea
                //printf("%d %d %d %d\n",frame->number,frame->timestamp.tv_usec,frame->size,frame->type);
1188
1189 8b52d5cf GiuseppeTropea
                if(frame->type != 5) { // video frame
1190 34149271 GiuseppeTropea
                        av_init_packet(&packet);
1191
                                packet.data = buffer;//video_bufQ;
1192
                                packet.size = frame->size;
1193
                                packet.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1194
                                packet.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1195
                                packet.stream_index = frame->number; // use of stream_index for number frame
1196
                                //packet.duration = frame->timestamp.tv_sec;
1197 88fe20d0 GiuseppeTropea
                        if(packet.size > 0)
1198
                                packet_queue_put(&videoq, &packet); //the _put makes a copy of the packet
1199 1e69ae95 GiuseppeTropea
#ifdef DEBUG_SOURCE
1200 34149271 GiuseppeTropea
                                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);
1201 1e69ae95 GiuseppeTropea
#endif
1202 34149271 GiuseppeTropea
                }
1203
                else { // audio frame
1204 f126ff44 GiuseppeTropea
1205 34149271 GiuseppeTropea
                        av_init_packet(&packetaudio);
1206
                        packetaudio.data = buffer;
1207
                        packetaudio.size = frame->size;
1208
                        packetaudio.pts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1209
                        packetaudio.dts = frame->timestamp.tv_sec*(unsigned long long)1000+frame->timestamp.tv_usec;
1210
                        //packetaudio.duration = frame->timestamp.tv_sec;
1211 f126ff44 GiuseppeTropea
                        packetaudio.stream_index = frame->number; // use of stream_index for number frame
1212 34149271 GiuseppeTropea
                        packetaudio.flags = 1;
1213
                        packetaudio.pos = -1;
1214 f126ff44 GiuseppeTropea
1215
                        //instead of -1, in order to signal it is not decoded yet
1216
                        packetaudio.convergence_duration = 0;
1217 34149271 GiuseppeTropea
1218
                        // insert the audio frame into the queue
1219 88fe20d0 GiuseppeTropea
                        if(packetaudio.size > 0)
1220
                                packet_queue_put(&audioq, &packetaudio);//makes a copy of the packet so i can free here
1221 1e69ae95 GiuseppeTropea
#ifdef DEBUG_SOURCE
1222 88fe20d0 GiuseppeTropea
                        printf("SOURCE: Insert audio in queue pts=%lld sindex:%d\n", packetaudio.pts, packetaudio.stream_index);
1223 1e69ae95 GiuseppeTropea
#endif
1224
                }
1225 8b52d5cf GiuseppeTropea
                j = j - sizeFrameHeader - frame->size;
1226 34149271 GiuseppeTropea
        }
1227 f126ff44 GiuseppeTropea
        if(echunk->data)
1228
                free(echunk->data);
1229
        if(echunk)
1230
                free(echunk);
1231
        if(frame)
1232
                free(frame);
1233
        if(audio_bufQ)
1234
                av_free(audio_bufQ);
1235 1e69ae95 GiuseppeTropea
}