Statistics
| Branch: | Revision:

chunker-player / chunker_streamer / chunker_streamer.c @ 795fe885

History | View | Annotate | Download (46.6 KB)

1 01f952d0 GiuseppeTropea
/*
2
 *  Copyright (c) 2009-2011 Carmelo Daniele, Dario Marchese, Diego Reforgiato, Giuseppe Tropea
3
 *  developed for the Napa-Wine EU project. See www.napa-wine.eu
4
 *
5
 *  This is free software; see lgpl-2.1.txt
6
 */
7 1e69ae95 GiuseppeTropea
8
#include "chunker_streamer.h"
9 e11386c0 CsabaKiraly
#include <signal.h>
10
#include <math.h>
11
#include <getopt.h>
12
#include <libswscale/swscale.h>
13 1e69ae95 GiuseppeTropea
14 51d67a10 Csaba Kiraly
#ifdef USE_AVFILTER
15
#include "chunker_filtering.h"
16
#endif
17
18 290b7b8c Csaba Kiraly
#define DEBUG
19
#define DEBUG_AUDIO_FRAMES  false
20
#define DEBUG_VIDEO_FRAMES  false
21
#define DEBUG_CHUNKER false
22
#define DEBUG_ANOMALIES true
23
#define DEBUG_TIMESTAMPING false
24 5d8321d3 napawine
#include "dbg.h"
25
26
#define STREAMER_MAX(a,b) ((a>b)?(a):(b))
27
#define STREAMER_MIN(a,b) ((a<b)?(a):(b))
28 290b7b8c Csaba Kiraly
29 9235dfb8 GiuseppeTropea
//#define DISPLAY_PSNR
30 e11386c0 CsabaKiraly
#define GET_PSNR(x) ((x==0) ? 0 : (-10.0*log(x)/log(10)))
31 69fd123e GiuseppeTropea
32 648357d7 GiuseppeTropea
ChunkerMetadata *cmeta = NULL;
33 269f1314 GiuseppeTropea
int seq_current_chunk = 1; //chunk numbering starts from 1; HINT do i need more bytes?
34 1e69ae95 GiuseppeTropea
35 e11386c0 CsabaKiraly
#define AUDIO_CHUNK 0
36
#define VIDEO_CHUNK 1
37
38
void SaveFrame(AVFrame *pFrame, int width, int height);
39
void SaveEncodedFrame(Frame* frame, uint8_t *video_outbuf);
40 31db59aa Csaba Kiraly
int pushChunkTcp(ExternalChunk *echunk);
41
void initTCPPush(char* ip, int port);
42
int update_chunk(ExternalChunk *chunk, Frame *frame, uint8_t *outbuf);
43
void finalizeTCPChunkPusher();
44
void bit32_encoded_push(uint32_t v, uint8_t *p);
45
46 e11386c0 CsabaKiraly
int video_record_count = 0;
47
int savedVideoFrames = 0;
48
long int firstSavedVideoFrame = 0;
49 31db59aa Csaba Kiraly
int ChunkerStreamerTestMode = 0;
50 1e69ae95 GiuseppeTropea
51 72d33062 Csaba Kiraly
int pts_anomaly_threshold = -1;
52
int newtime_anomaly_threshold = -1;
53 f35f46e8 Csaba Kiraly
bool timebank = false;
54 8ecce1bb Csaba Kiraly
char *outside_world_url = NULL;
55 36fdd607 Csaba Kiraly
56 6e690496 Csaba Kiraly
int gop_size = 25;
57 c0396779 Csaba Kiraly
int max_b_frames = 3;
58 b9477cd0 Csaba Kiraly
bool vcopy = false;
59
60 80515685 Csaba Kiraly
long delay_audio = 0; //delay audio by x millisec
61
62 51d67a10 Csaba Kiraly
char *avfilter="yadif";
63
64 e11386c0 CsabaKiraly
// Constant number of frames per chunk
65
int chunkFilledFramesStrategy(ExternalChunk *echunk, int chunkType)
66
{
67 290b7b8c Csaba Kiraly
        dcprintf(DEBUG_CHUNKER, "CHUNKER: check if frames num %d == %d in chunk %d\n", echunk->frames_num, cmeta->framesPerChunk[chunkType], echunk->seq);
68 e11386c0 CsabaKiraly
        if(echunk->frames_num == cmeta->framesPerChunk[chunkType])
69
                return 1;
70
71
        return 0;
72
}
73
74
// Constant size. Note that for now each chunk will have a size just greater or equal than the required value
75
// It can be considered as constant size.
76
int chunkFilledSizeStrategy(ExternalChunk *echunk, int chunkType)
77
{
78 290b7b8c Csaba Kiraly
        dcprintf(DEBUG_CHUNKER, "CHUNKER: check if chunk size %d >= %d in chunk %d\n", echunk->payload_len, cmeta->targetChunkSize, echunk->seq);
79 e11386c0 CsabaKiraly
        if(echunk->payload_len >= cmeta->targetChunkSize)
80
                return 1;
81 1e69ae95 GiuseppeTropea
        
82
        return 0;
83
}
84
85 e11386c0 CsabaKiraly
// Performace optimization.
86
// The chunkFilled function has been splitted into two functions (one for each strategy).
87
// Instead of continuously check the strategy flag (which is constant),
88
// we change the callback just once according to the current strategy (look at the switch statement in the main in which this function pointer is set)
89
int (*chunkFilled)(ExternalChunk *echunk, int chunkType);
90 1e69ae95 GiuseppeTropea
91 34149271 GiuseppeTropea
void initChunk(ExternalChunk *chunk, int *seq_num) {
92 1e69ae95 GiuseppeTropea
        chunk->seq = (*seq_num)++;
93
        chunk->frames_num = 0;
94
        chunk->payload_len = 0;
95
        chunk->len=0;
96 26379a77 GiuseppeTropea
  if(chunk->data != NULL)
97
    free(chunk->data);
98 1e69ae95 GiuseppeTropea
        chunk->data = NULL;
99
        chunk->start_time.tv_sec = -1;
100
        chunk->start_time.tv_usec = -1;
101
        chunk->end_time.tv_sec = -1;
102
        chunk->end_time.tv_usec = -1;
103
        chunk->priority = 0;
104
        chunk->category = 0;
105
        chunk->_refcnt = 0;
106
}
107
108 e11386c0 CsabaKiraly
int quit = 0;
109
110
void sigproc()
111
{
112
        printf("you have pressed ctrl-c, terminating...\n");
113
        quit = 1;
114
}
115
116
static void print_usage(int argc, char *argv[])
117
{
118
  fprintf (stderr,
119
    "\nUsage:%s [options]\n"
120
    "\n"
121
    "Mandatory options:\n"
122
    "\t[-i input file]\n"
123
    "\t[-a audio bitrate]\n"
124 8751781d Csaba Kiraly
    "\t[-v video bitrate]\n\n"
125 e11386c0 CsabaKiraly
    "Other options:\n"
126 8ecce1bb Csaba Kiraly
    "\t[-F output] (overrides config file)\n"
127 8751781d Csaba Kiraly
    "\t[-A audioencoder]\n"
128
    "\t[-V videoencoder]\n"
129 e11386c0 CsabaKiraly
    "\t[-s WxH]: force video size.\n"
130
    "\t[-l]: this is a live stream.\n"
131 b98fce85 Csaba Kiraly
    "\t[-o]: adjust A/V frame timestamps (deafault off, use it only with flawed containers)\n"
132 441ff227 Csaba Kiraly
    "\t[-p]: pts anomaly threshold (default: -1=off).\n"
133
    "\t[-q]: sync anomaly threshold ((default: -1=off).\n"
134 e11386c0 CsabaKiraly
    "\t[-t]: QoE test mode\n\n"
135 51d67a10 Csaba Kiraly
136 4206b310 Csaba Kiraly
    "\t[--video_stream]:set video_stream ID in input\n"
137
    "\t[--audio_stream]:set audio_stream ID in input\n"
138 51d67a10 Csaba Kiraly
    "\t[--avfilter]:set input filter (default: yadif\n"
139
    "\n"
140 db5d486a Csaba Kiraly
    "Codec options:\n"
141
    "\t[-g GOP]: gop size\n"
142 9cfd1b81 Csaba Kiraly
    "\t[-b frames]: max number of consecutive b frames\n"
143
    "\t[-x extas]: extra video codec options (e.g. -x me_method=hex,flags2=+dct8x8+wpred+bpyrami+mixed_refs)\n"
144
    "\n"
145 e11386c0 CsabaKiraly
    "=======================================================\n", argv[0]
146
    );
147
  }
148 8b52d5cf GiuseppeTropea
149 31db59aa Csaba Kiraly
int sendChunk(ExternalChunk *chunk) {
150 03590124 Csaba Kiraly
#ifdef HTTPIO
151 8ecce1bb Csaba Kiraly
                                                return pushChunkHttp(chunk, outside_world_url);
152 03590124 Csaba Kiraly
#endif
153
#ifdef TCPIO
154 31db59aa Csaba Kiraly
                                                return pushChunkTcp(chunk);
155 03590124 Csaba Kiraly
#endif
156 13836171 Csaba Kiraly
#ifdef UDPIO
157 31db59aa Csaba Kiraly
                                                return pushChunkUDP(chunk);
158 13836171 Csaba Kiraly
#endif
159 03590124 Csaba Kiraly
}
160
161 1e69ae95 GiuseppeTropea
int main(int argc, char *argv[]) {
162 e11386c0 CsabaKiraly
        signal(SIGINT, sigproc);
163
        
164 34149271 GiuseppeTropea
        int i=0;
165 648357d7 GiuseppeTropea
166
        //output variables
167
        uint8_t *video_outbuf = NULL;
168
        int video_outbuf_size, video_frame_size;
169
        uint8_t *audio_outbuf = NULL;
170
        int audio_outbuf_size, audio_frame_size;
171
        int audio_data_size;
172
173
        //numeric identifiers of input streams
174
        int videoStream = -1;
175
        int audioStream = -1;
176
177 31db59aa Csaba Kiraly
//        int len1;
178 1e69ae95 GiuseppeTropea
        int frameFinished;
179 648357d7 GiuseppeTropea
        //frame sequential counters
180 e11386c0 CsabaKiraly
        int contFrameAudio=1, contFrameVideo=0;
181 31db59aa Csaba Kiraly
//        int numBytes;
182 648357d7 GiuseppeTropea
183
        //command line parameters
184 e11386c0 CsabaKiraly
        int audio_bitrate = -1;
185
        int video_bitrate = -1;
186 2efccd13 Csaba Kiraly
        char *audio_codec = "mp2";
187
        char *video_codec = "mpeg4";
188 9cfd1b81 Csaba Kiraly
        char *codec_options = "";
189 c75b5711 GiuseppeTropea
        int live_source = 0; //tells to sleep before reading next frame in not live (i.e. file)
190
        int offset_av = 0; //tells to compensate for offset between audio and video in the file
191 1e69ae95 GiuseppeTropea
        
192 648357d7 GiuseppeTropea
        //a raw buffer for decoded uncompressed audio samples
193
        int16_t *samples = NULL;
194
        //a raw uncompressed video picture
195 51d67a10 Csaba Kiraly
        AVFrame *pFrame1 = NULL;
196
        AVFrame *pFrame2 = NULL;
197 e11386c0 CsabaKiraly
        AVFrame *scaledFrame = NULL;
198 11e39d44 GiuseppeTropea
199 1e69ae95 GiuseppeTropea
        AVFormatContext *pFormatCtx;
200 41e1f811 Csaba Kiraly
        AVCodecContext  *pCodecCtx = NULL ,*pCodecCtxEnc = NULL ,*aCodecCtxEnc = NULL ,*aCodecCtx = NULL;
201
        AVCodec         *pCodec = NULL ,*pCodecEnc = NULL ,*aCodec = NULL ,*aCodecEnc = NULL;
202 1e69ae95 GiuseppeTropea
        AVPacket         packet;
203
204 648357d7 GiuseppeTropea
        //stuff needed to compute the right timestamps
205 1e69ae95 GiuseppeTropea
        short int FirstTimeAudio=1, FirstTimeVideo=1;
206 eb0c9035 GiuseppeTropea
        short int pts_anomalies_counter=0;
207 df2ad829 GiuseppeTropea
        short int newtime_anomalies_counter=0;
208 0452f734 GiuseppeTropea
        long long newTime=0, newTime_audio=0, newTime_video=0, newTime_prev=0;
209 69fd123e GiuseppeTropea
        struct timeval lastAudioSent = {0, 0};
210 2018e261 Csaba Kiraly
        int64_t ptsvideo1=0;
211
        int64_t ptsaudio1=0;
212 648357d7 GiuseppeTropea
        int64_t last_pkt_dts=0, delta_video=0, delta_audio=0, last_pkt_dts_audio=0, target_pts=0;
213
214 8b52d5cf GiuseppeTropea
        //Napa-Wine specific Frame and Chunk structures for transport
215
        Frame *frame = NULL;
216
        ExternalChunk *chunk = NULL;
217
        ExternalChunk *chunkaudio = NULL;
218 e11386c0 CsabaKiraly
        
219
        char av_input[1024];
220
        int dest_width = -1;
221
        int dest_height = -1;
222
        
223
        static struct option long_options[] =
224
        {
225 7efb9318 Csaba Kiraly
                {"audio_stream", required_argument, 0, 0},
226
                {"video_stream", required_argument, 0, 0},
227 51d67a10 Csaba Kiraly
                {"avfilter", required_argument, 0, 0},
228 e11386c0 CsabaKiraly
                {0, 0, 0, 0}
229
        };
230
        /* `getopt_long' stores the option index here. */
231
        int option_index = 0, c;
232
        int mandatories = 0;
233 9cfd1b81 Csaba Kiraly
        while ((c = getopt_long (argc, argv, "i:a:v:A:V:s:lop:q:tF:g:b:d:x:", long_options, &option_index)) != -1)
234 e11386c0 CsabaKiraly
        {
235
                switch (c) {
236
                        case 0: //for long options
237 7efb9318 Csaba Kiraly
                                if( strcmp( "audio_stream", long_options[option_index].name ) == 0 ) { audioStream = atoi(optarg); }
238
                                if( strcmp( "video_stream", long_options[option_index].name ) == 0 ) { videoStream = atoi(optarg); }
239 51d67a10 Csaba Kiraly
                                if( strcmp( "avfilter", long_options[option_index].name ) == 0 ) { avfilter = strdup(optarg); }
240 e11386c0 CsabaKiraly
                                break;
241
                        case 'i':
242
                                sprintf(av_input, "%s", optarg);
243
                                mandatories++;
244
                                break;
245
                        case 'a':
246
                                sscanf(optarg, "%d", &audio_bitrate);
247
                                mandatories++;
248
                                break;
249
                        case 'v':
250
                                sscanf(optarg, "%d", &video_bitrate);
251
                                mandatories++;
252
                                break;
253 2efccd13 Csaba Kiraly
                        case 'A':
254
                                audio_codec = strdup(optarg);
255
                                break;
256
                        case 'V':
257
                                video_codec = strdup(optarg);
258
                                break;
259 e11386c0 CsabaKiraly
                        case 's':
260
                                sscanf(optarg, "%dx%d", &dest_width, &dest_height);
261
                                break;
262
                        case 'l':
263
                                live_source = 1;
264
                                break;
265
                        case 'o':
266
                                offset_av = 1;
267
                                break;
268
                        case 't':
269
                                ChunkerStreamerTestMode = 1;
270
                                break;
271 441ff227 Csaba Kiraly
                        case 'p':
272
                                sscanf(optarg, "%d", &pts_anomaly_threshold);
273
                                break;
274
                        case 'q':
275
                                sscanf(optarg, "%d", &newtime_anomaly_threshold);
276
                                break;
277 8ecce1bb Csaba Kiraly
                        case 'F':
278
                                outside_world_url = strdup(optarg);
279
                                break;
280 db5d486a Csaba Kiraly
                        case 'g':
281
                                sscanf(optarg, "%d", &gop_size);
282
                                break;
283
                        case 'b':
284
                                sscanf(optarg, "%d", &max_b_frames);
285
                                break;
286 80515685 Csaba Kiraly
                        case 'd':
287 fe9cdf9a GiuseppeTropea
                                sscanf(optarg, "%ld", &delay_audio);
288 80515685 Csaba Kiraly
                                break;
289 9cfd1b81 Csaba Kiraly
                        case 'x':
290
                                codec_options = strdup(optarg);
291
                                break;
292 e11386c0 CsabaKiraly
                        default:
293
                                print_usage(argc, argv);
294
                                return -1;
295
                }
296
        }
297
        
298
        if(mandatories < 3) 
299
        {
300
                print_usage(argc, argv);
301 1e69ae95 GiuseppeTropea
                return -1;
302
        }
303 e11386c0 CsabaKiraly
304
#ifdef YUV_RECORD_ENABLED
305
        if(ChunkerStreamerTestMode)
306
        {
307
                DELETE_DIR("yuv_data");
308
                CREATE_DIR("yuv_data");
309
                //FILE* pFile=fopen("yuv_data/streamer_out.yuv", "w");
310
                //fclose(pFile);
311
        }
312
#endif
313 34149271 GiuseppeTropea
314 ac723195 GiuseppeTropea
restart:
315 34149271 GiuseppeTropea
        // read the configuration file
316
        cmeta = chunkerInit();
317 8ecce1bb Csaba Kiraly
        if (!outside_world_url) {
318
                outside_world_url = strdup(cmeta->outside_world_url);
319
        }
320 e11386c0 CsabaKiraly
        switch(cmeta->strategy)
321
        {
322
                case 1:
323
                        chunkFilled = chunkFilledSizeStrategy;
324
                        break;
325
                default:
326
                        chunkFilled = chunkFilledFramesStrategy;
327
        }
328
                
329 34149271 GiuseppeTropea
        if(live_source)
330
                fprintf(stderr, "INIT: Using LIVE SOURCE TimeStamps\n");
331 c75b5711 GiuseppeTropea
        if(offset_av)
332
                fprintf(stderr, "INIT: Compensating AV OFFSET in file\n");
333 1e69ae95 GiuseppeTropea
334
        // Register all formats and codecs
335
        av_register_all();
336
337 648357d7 GiuseppeTropea
        // Open input file
338 e11386c0 CsabaKiraly
        if(av_open_input_file(&pFormatCtx, av_input, NULL, 0, NULL) != 0) {
339 34149271 GiuseppeTropea
                fprintf(stdout, "INIT: Couldn't open video file. Exiting.\n");
340
                exit(-1);
341
        }
342
343 1e69ae95 GiuseppeTropea
        // Retrieve stream information
344 34149271 GiuseppeTropea
        if(av_find_stream_info(pFormatCtx) < 0) {
345
                fprintf(stdout, "INIT: Couldn't find stream information. Exiting.\n");
346
                exit(-1);
347
        }
348
349 1e69ae95 GiuseppeTropea
        // Dump information about file onto standard error
350 fe9cdf9a GiuseppeTropea
        av_dump_format(pFormatCtx, 0, av_input, 0);
351 34149271 GiuseppeTropea
352 648357d7 GiuseppeTropea
        // Find the video and audio stream numbers
353 1e69ae95 GiuseppeTropea
        for(i=0; i<pFormatCtx->nb_streams; i++) {
354
                if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream<0) {
355
                        videoStream=i;
356
                }
357
                if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && audioStream<0) {
358
                        audioStream=i;
359
                }
360
        }
361 d2864dba Csaba Kiraly
362
        if(videoStream==-1 || audioStream==-1) {        // TODO: refine to work with 1 or the other
363
                fprintf(stdout, "INIT: Didn't find audio and video streams. Exiting.\n");
364
                exit(-1);
365
        }
366
367 fe9cdf9a GiuseppeTropea
        fprintf(stderr, "INIT: Num streams : %d TBR: %d %d RFRAMERATE:%d %d Duration:%ld\n", pFormatCtx->nb_streams, pFormatCtx->streams[videoStream]->time_base.num, pFormatCtx->streams[videoStream]->time_base.den, pFormatCtx->streams[videoStream]->r_frame_rate.num, pFormatCtx->streams[videoStream]->r_frame_rate.den, (long int)pFormatCtx->streams[videoStream]->duration);
368 e810bf7b GiuseppeTropea
369 34149271 GiuseppeTropea
        fprintf(stderr, "INIT: Video stream has id : %d\n",videoStream);
370
        fprintf(stderr, "INIT: Audio stream has id : %d\n",audioStream);
371
372 1e69ae95 GiuseppeTropea
373 648357d7 GiuseppeTropea
        // Get a pointer to the codec context for the input video stream
374 1e69ae95 GiuseppeTropea
        pCodecCtx=pFormatCtx->streams[videoStream]->codec;
375
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
376 648357d7 GiuseppeTropea
        //extract W and H
377
        fprintf(stderr, "INIT: Width:%d Height:%d\n", pCodecCtx->width, pCodecCtx->height);
378 1e69ae95 GiuseppeTropea
379 648357d7 GiuseppeTropea
        // Get a pointer to the codec context for the input audio stream
380
        if(audioStream != -1) {
381 1e69ae95 GiuseppeTropea
                aCodecCtx=pFormatCtx->streams[audioStream]->codec;
382 34149271 GiuseppeTropea
                fprintf(stderr, "INIT: AUDIO Codecid: %d channels %d samplerate %d\n", aCodecCtx->codec_id, aCodecCtx->channels, aCodecCtx->sample_rate);
383 1e69ae95 GiuseppeTropea
        }
384
385 387b789d Csaba Kiraly
        // Figure out size
386
        dest_width = (dest_width > 0) ? dest_width : pCodecCtx->width;
387
        dest_height = (dest_height > 0) ? dest_height : pCodecCtx->height;
388
389 648357d7 GiuseppeTropea
        //setup video output encoder
390 b9477cd0 Csaba Kiraly
 if (strcmp(video_codec, "copy") == 0) {
391
        vcopy = true;
392
 } else {
393 2efccd13 Csaba Kiraly
        pCodecEnc = avcodec_find_encoder_by_name(video_codec);
394
        if (pCodecEnc) {
395
                fprintf(stderr, "INIT: Setting VIDEO codecID to: %d\n",pCodecEnc->id);
396
        } else {
397
                fprintf(stderr, "INIT: Unknown OUT VIDEO codec: %s!\n", video_codec);
398
                return -1; // Codec not found
399
        }
400
401 1e69ae95 GiuseppeTropea
        pCodecCtxEnc=avcodec_alloc_context();
402
        pCodecCtxEnc->codec_type = CODEC_TYPE_VIDEO;
403 2efccd13 Csaba Kiraly
        pCodecCtxEnc->codec_id = pCodecEnc->id;
404
405
        pCodecCtxEnc->bit_rate = video_bitrate;
406
        //~ pCodecCtxEnc->qmin = 30;
407
        //~ pCodecCtxEnc->qmax = 30;
408
        //times 20 follows the defaults, was not needed in previous versions of libavcodec
409
//        pCodecCtxEnc->crf = 20.0f;
410 1e69ae95 GiuseppeTropea
        // resolution must be a multiple of two 
411 387b789d Csaba Kiraly
        pCodecCtxEnc->width = dest_width;
412
        pCodecCtxEnc->height = dest_height;
413 1e69ae95 GiuseppeTropea
        // frames per second 
414 2efccd13 Csaba Kiraly
        //~ pCodecCtxEnc->time_base= pCodecCtx->time_base;//(AVRational){1,25};
415
        //printf("pCodecCtx->time_base=%d/%d\n", pCodecCtx->time_base.num, pCodecCtx->time_base.den);
416 11e39d44 GiuseppeTropea
        pCodecCtxEnc->time_base= pCodecCtx->time_base;//(AVRational){1,25};
417 db5d486a Csaba Kiraly
        pCodecCtxEnc->gop_size = gop_size; // emit one intra frame every gop_size frames 
418
        pCodecCtxEnc->max_b_frames = max_b_frames;
419 1e69ae95 GiuseppeTropea
        pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P;
420 9235dfb8 GiuseppeTropea
        pCodecCtxEnc->flags |= CODEC_FLAG_PSNR;
421 2efccd13 Csaba Kiraly
        //~ pCodecCtxEnc->flags |= CODEC_FLAG_QSCALE;
422 dfda9829 Csaba Kiraly
423
        //some generic quality tuning
424
        pCodecCtxEnc->mb_decision = FF_MB_DECISION_RD;
425
426 42fb3c39 Csaba Kiraly
        //some rate control parameters for streaming, taken from ffserver.c
427
        {
428
        /* Bitrate tolerance is less for streaming */
429
        AVCodecContext *av = pCodecCtxEnc;
430
        if (av->bit_rate_tolerance == 0)
431
            av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
432
                      (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
433 f15d4ed0 Csaba Kiraly
        //if (av->qmin == 0)
434
        //    av->qmin = 3;
435
        //if (av->qmax == 0)
436
        //    av->qmax = 31;
437
        //if (av->max_qdiff == 0)
438
        //    av->max_qdiff = 3;
439
        //av->qcompress = 0.5;
440
        //av->qblur = 0.5;
441
442
        //if (!av->nsse_weight)
443
        //    av->nsse_weight = 8;
444
445
        //av->frame_skip_cmp = FF_CMP_DCTMAX;
446
        //if (!av->me_method)
447
        //    av->me_method = ME_EPZS;
448
        //av->rc_buffer_aggressivity = 1.0;
449 42fb3c39 Csaba Kiraly
450 c019be0f Csaba Kiraly
        //if (!av->rc_eq)
451
        //    av->rc_eq = "tex^qComp";
452 f15d4ed0 Csaba Kiraly
        //if (!av->i_quant_factor)
453
        //    av->i_quant_factor = -0.8;
454
        //if (!av->b_quant_factor)
455
        //    av->b_quant_factor = 1.25;
456
        //if (!av->b_quant_offset)
457
        //    av->b_quant_offset = 1.25;
458 42fb3c39 Csaba Kiraly
        if (!av->rc_max_rate)
459
            av->rc_max_rate = av->bit_rate * 2;
460
461
        if (av->rc_max_rate && !av->rc_buffer_size) {
462
            av->rc_buffer_size = av->rc_max_rate;
463
        }
464
        }
465
        //end of code taken fromffserver.c
466
467 2efccd13 Csaba Kiraly
  switch (pCodecEnc->id) {
468
    case CODEC_ID_H264 :
469 046e7b49 napawine
        // Fast Profile
470
        // libx264-fast.ffpreset preset 
471
        pCodecCtxEnc->coder_type = FF_CODER_TYPE_AC; // coder = 1 -> enable CABAC
472
        pCodecCtxEnc->flags |= CODEC_FLAG_LOOP_FILTER; // flags=+loop -> deblock
473
        pCodecCtxEnc->me_cmp|= 1; // cmp=+chroma, where CHROMA = 1
474
        pCodecCtxEnc->partitions |= X264_PART_I8X8|X264_PART_I4X4|X264_PART_P8X8|X264_PART_B8X8;        // partitions=+parti8x8+parti4x4+partp8x8+partb8x8
475
        pCodecCtxEnc->me_method=ME_HEX; // me_method=hex
476
        pCodecCtxEnc->me_subpel_quality = 6; // subq=7
477
        pCodecCtxEnc->me_range = 16; // me_range=16
478
        //pCodecCtxEnc->gop_size = 250; // g=250
479
        //pCodecCtxEnc->keyint_min = 25; // keyint_min=25
480
        pCodecCtxEnc->scenechange_threshold = 40; // sc_threshold=40
481
        pCodecCtxEnc->i_quant_factor = 0.71; // i_qfactor=0.71
482
        pCodecCtxEnc->b_frame_strategy = 1; // b_strategy=1
483
        pCodecCtxEnc->qcompress = 0.6; // qcomp=0.6
484
        pCodecCtxEnc->qmin = 10; // qmin=10
485
        pCodecCtxEnc->qmax = 51; // qmax=51
486
        pCodecCtxEnc->max_qdiff = 4; // qdiff=4
487
        //pCodecCtxEnc->max_b_frames = 3; // bf=3
488
        pCodecCtxEnc->refs = 2; // refs=3
489
        //pCodecCtxEnc->directpred = 1; // directpred=1
490
        pCodecCtxEnc->directpred = 3; // directpred=1 in preset -> "directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)"
491
        //pCodecCtxEnc->trellis = 1; // trellis=1
492
        pCodecCtxEnc->flags2 |= CODEC_FLAG2_BPYRAMID|CODEC_FLAG2_MIXED_REFS|CODEC_FLAG2_WPRED|CODEC_FLAG2_8X8DCT|CODEC_FLAG2_FASTPSKIP;        // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
493
        pCodecCtxEnc->weighted_p_pred = 2; // wpredp=2
494
495
        // libx264-main.ffpreset preset
496
        //pCodecCtxEnc->flags2|=CODEC_FLAG2_8X8DCT;
497
        //pCodecCtxEnc->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8
498
        //pCodecCtxEnc->crf = 22;
499 4c879040 GiuseppeTropea
500 e11386c0 CsabaKiraly
#ifdef STREAMER_X264_USE_SSIM
501
        pCodecCtxEnc->flags2 |= CODEC_FLAG2_SSIM;
502
#endif
503
504 046e7b49 napawine
        //pCodecCtxEnc->weighted_p_pred=2; //maps wpredp=2; weighted prediction analysis method
505 e11386c0 CsabaKiraly
        // pCodecCtxEnc->rc_min_rate = 0;
506
        // pCodecCtxEnc->rc_max_rate = video_bitrate*2;
507
        // pCodecCtxEnc->rc_buffer_size = 0;
508 2efccd13 Csaba Kiraly
        break;
509
    case CODEC_ID_MPEG4 :
510
        break;
511
    default:
512
        fprintf(stderr, "INIT: Unsupported OUT VIDEO codec: %s!\n", video_codec);
513
  }
514 9cfd1b81 Csaba Kiraly
515
  if ((av_set_options_string(pCodecCtxEnc, codec_options, "=", ",")) < 0) {
516
    fprintf(stderr, "Error parsing options string: '%s'\n", codec_options);
517
    exit(1);
518
  }
519
520 34149271 GiuseppeTropea
        fprintf(stderr, "INIT: VIDEO timebase OUT:%d %d IN: %d %d\n", pCodecCtxEnc->time_base.num, pCodecCtxEnc->time_base.den, pCodecCtx->time_base.num, pCodecCtx->time_base.den);
521 b9477cd0 Csaba Kiraly
 }
522 e810bf7b GiuseppeTropea
523 648357d7 GiuseppeTropea
        if(pCodec==NULL) {
524
                fprintf(stderr, "INIT: Unsupported IN VIDEO pcodec!\n");
525
                return -1; // Codec not found
526
        }
527 b9477cd0 Csaba Kiraly
        if(!vcopy && pCodecEnc==NULL) {
528 648357d7 GiuseppeTropea
                fprintf(stderr, "INIT: Unsupported OUT VIDEO pcodecenc!\n");
529
                return -1; // Codec not found
530
        }
531
        if(avcodec_open(pCodecCtx, pCodec)<0) {
532
                fprintf(stderr, "INIT: could not open IN VIDEO codec\n");
533
                return -1; // Could not open codec
534
        }
535 b9477cd0 Csaba Kiraly
        if(!vcopy && avcodec_open(pCodecCtxEnc, pCodecEnc)<0) {
536 648357d7 GiuseppeTropea
                fprintf(stderr, "INIT: could not open OUT VIDEO codecEnc\n");
537
                return -1; // Could not open codec
538
        }
539 1e69ae95 GiuseppeTropea
        if(audioStream!=-1) {
540 0452f734 GiuseppeTropea
                //setup audio output encoder
541
                aCodecCtxEnc = avcodec_alloc_context();
542
                aCodecCtxEnc->bit_rate = audio_bitrate; //256000
543
                aCodecCtxEnc->sample_fmt = SAMPLE_FMT_S16;
544
                aCodecCtxEnc->sample_rate = aCodecCtx->sample_rate;
545
                aCodecCtxEnc->channels = aCodecCtx->channels;
546
                fprintf(stderr, "INIT: AUDIO bitrate OUT:%d sample_rate:%d channels:%d\n", aCodecCtxEnc->bit_rate, aCodecCtxEnc->sample_rate, aCodecCtxEnc->channels);
547
548
                // Find the decoder for the audio stream
549 1e69ae95 GiuseppeTropea
                aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
550 2efccd13 Csaba Kiraly
                aCodecEnc = avcodec_find_encoder_by_name(audio_codec);
551 1e69ae95 GiuseppeTropea
                if(aCodec==NULL) {
552 34149271 GiuseppeTropea
                        fprintf(stderr,"INIT: Unsupported acodec!\n");
553 1e69ae95 GiuseppeTropea
                        return -1;
554
                }
555
                if(aCodecEnc==NULL) {
556 34149271 GiuseppeTropea
                        fprintf(stderr,"INIT: Unsupported acodecEnc!\n");
557 1e69ae95 GiuseppeTropea
                        return -1;
558
                }
559
        
560
                if(avcodec_open(aCodecCtx, aCodec)<0) {
561 34149271 GiuseppeTropea
                        fprintf(stderr, "INIT: could not open IN AUDIO codec\n");
562 1e69ae95 GiuseppeTropea
                        return -1; // Could not open codec
563
                }
564
                if(avcodec_open(aCodecCtxEnc, aCodecEnc)<0) {
565 34149271 GiuseppeTropea
                        fprintf(stderr, "INIT: could not open OUT AUDIO codec\n");
566 1e69ae95 GiuseppeTropea
                        return -1; // Could not open codec
567
                }
568
        }
569 0452f734 GiuseppeTropea
        else {
570
                fprintf(stderr,"INIT: NO AUDIO TRACK IN INPUT FILE\n");
571
        }
572 648357d7 GiuseppeTropea
573
        // Allocate audio in and out buffers
574
        samples = (int16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
575
        if(samples == NULL) {
576
                fprintf(stderr, "INIT: Memory error alloc audio samples!!!\n");
577
                return -1;
578 1e69ae95 GiuseppeTropea
        }
579 648357d7 GiuseppeTropea
        audio_outbuf_size = STREAMER_MAX_AUDIO_BUFFER_SIZE;
580
        audio_outbuf = av_malloc(audio_outbuf_size);
581
        if(audio_outbuf == NULL) {
582
                fprintf(stderr, "INIT: Memory error alloc audio_outbuf!!!\n");
583
                return -1;
584 1e69ae95 GiuseppeTropea
        }
585
586 648357d7 GiuseppeTropea
        // Allocate video in frame and out buffer
587 51d67a10 Csaba Kiraly
        pFrame1=avcodec_alloc_frame();
588
        pFrame2=avcodec_alloc_frame();
589 e11386c0 CsabaKiraly
        scaledFrame=avcodec_alloc_frame();
590 51d67a10 Csaba Kiraly
        if(pFrame1==NULL || pFrame2==NULL || scaledFrame == NULL) {
591 34149271 GiuseppeTropea
                fprintf(stderr, "INIT: Memory error alloc video frame!!!\n");
592 1e69ae95 GiuseppeTropea
                return -1;
593
        }
594 648357d7 GiuseppeTropea
        video_outbuf_size = STREAMER_MAX_VIDEO_BUFFER_SIZE;
595
        video_outbuf = av_malloc(video_outbuf_size);
596 387b789d Csaba Kiraly
        int scaledFrame_buf_size = avpicture_get_size( PIX_FMT_YUV420P, dest_width, dest_height);
597 e11386c0 CsabaKiraly
        uint8_t* scaledFrame_buffer = (uint8_t *) av_malloc( scaledFrame_buf_size * sizeof( uint8_t ) );
598 387b789d Csaba Kiraly
        avpicture_fill( (AVPicture*) scaledFrame, scaledFrame_buffer, PIX_FMT_YUV420P, dest_width, dest_height);
599 e11386c0 CsabaKiraly
        if(!video_outbuf || !scaledFrame_buffer) {
600 648357d7 GiuseppeTropea
                fprintf(stderr, "INIT: Memory error alloc video_outbuf!!!\n");
601 1e69ae95 GiuseppeTropea
                return -1;
602
        }
603 648357d7 GiuseppeTropea
604
        //allocate Napa-Wine transport
605 1e69ae95 GiuseppeTropea
        frame = (Frame *)malloc(sizeof(Frame));
606
        if(!frame) {
607 34149271 GiuseppeTropea
                fprintf(stderr, "INIT: Memory error alloc Frame!!!\n");
608 1e69ae95 GiuseppeTropea
                return -1;
609
        }
610 269f1314 GiuseppeTropea
        //create an empty first video chunk
611 1e69ae95 GiuseppeTropea
        chunk = (ExternalChunk *)malloc(sizeof(ExternalChunk));
612
        if(!chunk) {
613 34149271 GiuseppeTropea
                fprintf(stderr, "INIT: Memory error alloc chunk!!!\n");
614 1e69ae95 GiuseppeTropea
                return -1;
615
        }
616 269f1314 GiuseppeTropea
        chunk->data = NULL;
617
        chunk->seq = 0;
618
        //initChunk(chunk, &seq_current_chunk); if i init them now i get out of sequence
619 290b7b8c Csaba Kiraly
        dcprintf(DEBUG_CHUNKER, "INIT: chunk video %d\n", chunk->seq);
620 269f1314 GiuseppeTropea
        //create empty first audio chunk
621 1e69ae95 GiuseppeTropea
        chunkaudio = (ExternalChunk *)malloc(sizeof(ExternalChunk));
622
        if(!chunkaudio) {
623 34149271 GiuseppeTropea
                fprintf(stderr, "INIT: Memory error alloc chunkaudio!!!\n");
624 1e69ae95 GiuseppeTropea
                return -1;
625
        }
626 648357d7 GiuseppeTropea
  chunkaudio->data=NULL;
627 269f1314 GiuseppeTropea
        chunkaudio->seq = 0;
628
        //initChunk(chunkaudio, &seq_current_chunk);
629 290b7b8c Csaba Kiraly
        dcprintf(DEBUG_CHUNKER, "INIT: chunk audio %d\n", chunkaudio->seq);
630 1e69ae95 GiuseppeTropea
631 03590124 Csaba Kiraly
#ifdef HTTPIO
632 1e69ae95 GiuseppeTropea
        /* initialize the HTTP chunk pusher */
633 8de6681e GiuseppeTropea
        initChunkPusher(); //TRIPLO
634 03590124 Csaba Kiraly
#endif
635 1e69ae95 GiuseppeTropea
636 4c879040 GiuseppeTropea
        long sleep=0;
637 69fd123e GiuseppeTropea
        struct timeval now_tv;
638
        struct timeval tmp_tv;
639
        long long lateTime = 0;
640
        long long maxAudioInterval = 0;
641
        long long maxVDecodeTime = 0;
642 31db59aa Csaba Kiraly
//        unsigned char lastIFrameDistance = 0;
643 e11386c0 CsabaKiraly
644
#ifdef TCPIO
645
        static char peer_ip[16];
646
        static int peer_port;
647 8ecce1bb Csaba Kiraly
        int res = sscanf(outside_world_url, "tcp://%15[0-9.]:%d", peer_ip, &peer_port);
648 e11386c0 CsabaKiraly
        if (res < 2) {
649 8ecce1bb Csaba Kiraly
                fprintf(stderr,"error parsing output url: %s\n", outside_world_url);
650 e11386c0 CsabaKiraly
                return -2;
651
        }
652
        
653
        initTCPPush(peer_ip, peer_port);
654
#endif
655 13836171 Csaba Kiraly
#ifdef UDPIO
656
        static char peer_ip[16];
657
        static int peer_port;
658 8ecce1bb Csaba Kiraly
        int res = sscanf(outside_world_url, "udp://%15[0-9.]:%d", peer_ip, &peer_port);
659 13836171 Csaba Kiraly
        if (res < 2) {
660 8ecce1bb Csaba Kiraly
                fprintf(stderr,"error parsing output url: %s\n", outside_world_url);
661 13836171 Csaba Kiraly
                return -2;
662
        }
663
        
664
        initUDPPush(peer_ip, peer_port);
665
#endif
666 e11386c0 CsabaKiraly
        
667
        char videotrace_filename[255];
668
        char psnr_filename[255];
669
        sprintf(videotrace_filename, "yuv_data/videotrace.log");
670
        sprintf(psnr_filename, "yuv_data/psnrtrace.log");
671
        FILE* videotrace = fopen(videotrace_filename, "w");
672
        FILE* psnrtrace = fopen(psnr_filename, "w");
673 ac723195 GiuseppeTropea
674 51d67a10 Csaba Kiraly
#ifdef USE_AVFILTER
675
        //init AVFilter
676
        avfilter_register_all();
677
        init_filters(avfilter, pCodecCtx);
678
#endif
679
680 648357d7 GiuseppeTropea
        //main loop to read from the input file
681 e11386c0 CsabaKiraly
        while((av_read_frame(pFormatCtx, &packet)>=0) && !quit)
682 69fd123e GiuseppeTropea
        {
683 4c879040 GiuseppeTropea
                //detect if a strange number of anomalies is occurring
684 eb0c9035 GiuseppeTropea
                if(ptsvideo1 < 0 || ptsvideo1 > packet.dts || ptsaudio1 < 0 || ptsaudio1 > packet.dts) {
685
                        pts_anomalies_counter++;
686 290b7b8c Csaba Kiraly
                        dcprintf(DEBUG_ANOMALIES, "READLOOP: pts BASE anomaly detected number %d\n", pts_anomalies_counter);
687 036a95a6 Csaba Kiraly
                        if(pts_anomaly_threshold >=0 && live_source) { //reset just in case of live source
688 36fdd607 Csaba Kiraly
                                if(pts_anomalies_counter > pts_anomaly_threshold) {
689 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_ANOMALIES, "READLOOP: too many pts BASE anomalies. resetting pts base\n");
690 98cbdb77 Csaba Kiraly
                                        av_free_packet(&packet);
691
                                        goto close;
692 eb0c9035 GiuseppeTropea
                                }
693
                        }
694
                }
695
696 e11386c0 CsabaKiraly
                //newTime_video and _audio are in usec
697
                //if video and audio stamps differ more than 5sec
698
                if( newTime_video - newTime_audio > 5000000 || newTime_video - newTime_audio < -5000000 ) {
699
                        newtime_anomalies_counter++;
700 290b7b8c Csaba Kiraly
                        dcprintf(DEBUG_ANOMALIES, "READLOOP: NEWTIME audio video differ anomaly detected number %d\n", newtime_anomalies_counter);
701 e11386c0 CsabaKiraly
                }
702
703 036a95a6 Csaba Kiraly
                if(newtime_anomaly_threshold >=0 && newtime_anomalies_counter > newtime_anomaly_threshold) {
704 df2ad829 GiuseppeTropea
                        if(live_source) { //restart just in case of live source
705 290b7b8c Csaba Kiraly
                                dcprintf(DEBUG_ANOMALIES, "READLOOP: too many NEGATIVE TIMESTAMPS anomalies. Restarting.\n");
706 d25320f1 Csaba Kiraly
                                av_free_packet(&packet);
707 df2ad829 GiuseppeTropea
                                goto close;
708
                        }
709
                }
710
711 1e69ae95 GiuseppeTropea
                // Is this a packet from the video stream?
712 69fd123e GiuseppeTropea
                if(packet.stream_index==videoStream)
713
                {
714
                        if(!live_source)
715
                        {
716 e11386c0 CsabaKiraly
                                if(audioStream != -1) { //take this "time bank" method into account only if we have audio track
717
                                        // lateTime < 0 means a positive time account that can be used to decode video frames
718
                                        // if (lateTime + maxVDecodeTime) >= 0 then we may have a negative time account after video transcoding
719
                                        // therefore, it's better to skip the frame
720 dc3cdade Csaba Kiraly
                                        if(timebank && (lateTime+maxVDecodeTime) >= 0)
721 e11386c0 CsabaKiraly
                                        {
722 290b7b8c Csaba Kiraly
                                                dcprintf(DEBUG_ANOMALIES, "\n\n\t\t************************* SKIPPING VIDEO FRAME %ld ***********************************\n\n", sleep);
723 0fe99630 Csaba Kiraly
                                                av_free_packet(&packet);
724 e11386c0 CsabaKiraly
                                                continue;
725
                                        }
726 69fd123e GiuseppeTropea
                                }
727
                        }
728
                        
729
                        gettimeofday(&tmp_tv, NULL);
730
                        
731 648357d7 GiuseppeTropea
                        //decode the video packet into a raw pFrame
732 51d67a10 Csaba Kiraly
                        if(avcodec_decode_video2(pCodecCtx, pFrame1, &frameFinished, &packet)>0)
733 69fd123e GiuseppeTropea
                        {
734 51d67a10 Csaba Kiraly
                                AVFrame *pFrame;
735
                                pFrame = pFrame1;
736
737 69fd123e GiuseppeTropea
                                // usleep(5000);
738 795fe885 Csaba Kiraly
                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOin pkt: dts %"PRId64" pts %"PRId64" pts-dts %"PRId64"\n", packet.dts, packet.pts, packet.pts-packet.dts );
739
                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode: pkt_dts %"PRId64" pkt_pts %"PRId64" frame.pts %"PRId64"\n", pFrame->pkt_dts, pFrame->pkt_pts, pFrame->pts);
740 290b7b8c Csaba Kiraly
                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode intype %d%s\n", pFrame->pict_type, pFrame->key_frame ? " (key)" : "");
741 e11386c0 CsabaKiraly
                                if(frameFinished)
742
                                { // it must be true all the time else error
743
                                
744
                                        frame->number = ++contFrameVideo;
745
746
#ifdef VIDEO_DEINTERLACE
747 b9477cd0 Csaba Kiraly
                                if (!vcopy) {
748 e11386c0 CsabaKiraly
                                        avpicture_deinterlace(
749
                                                (AVPicture*) pFrame,
750
                                                (const AVPicture*) pFrame,
751
                                                pCodecCtxEnc->pix_fmt,
752
                                                pCodecCtxEnc->width,
753
                                                pCodecCtxEnc->height);
754 b9477cd0 Csaba Kiraly
                                }
755 e11386c0 CsabaKiraly
#endif
756
757 51d67a10 Csaba Kiraly
758 795fe885 Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: finished frame %d dts %"PRId64" pts %"PRId64"\n", frame->number, packet.dts, packet.pts);
759 e810bf7b GiuseppeTropea
                                        if(frame->number==0) {
760
                                                if(packet.dts==AV_NOPTS_VALUE)
761 e11386c0 CsabaKiraly
                                                {
762 34149271 GiuseppeTropea
                                                        //a Dts with a noPts value is troublesome case for delta calculation based on Dts
763 e11386c0 CsabaKiraly
                                                        contFrameVideo = STREAMER_MAX(contFrameVideo-1, 0);
764 0fe99630 Csaba Kiraly
                                                        av_free_packet(&packet);
765 e810bf7b GiuseppeTropea
                                                        continue;
766 e11386c0 CsabaKiraly
                                                }
767 e810bf7b GiuseppeTropea
                                                last_pkt_dts = packet.dts;
768
                                                newTime = 0;
769
                                        }
770
                                        else {
771
                                                if(packet.dts!=AV_NOPTS_VALUE) {
772 34149271 GiuseppeTropea
                                                        delta_video = packet.dts-last_pkt_dts;
773 e810bf7b GiuseppeTropea
                                                        last_pkt_dts = packet.dts;
774
                                                }
775 34149271 GiuseppeTropea
                                                else if(delta_video==0)
776 e11386c0 CsabaKiraly
                                                {
777 34149271 GiuseppeTropea
                                                        //a Dts with a noPts value is troublesome case for delta calculation based on Dts
778 e11386c0 CsabaKiraly
                                                        contFrameVideo = STREAMER_MAX(contFrameVideo-1, 0);
779 0fe99630 Csaba Kiraly
                                                        av_free_packet(&packet);
780 e810bf7b GiuseppeTropea
                                                        continue;
781 e11386c0 CsabaKiraly
                                                }
782 e810bf7b GiuseppeTropea
                                        }
783 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: deltavideo : %d\n", (int)delta_video);
784 e11386c0 CsabaKiraly
785 b9477cd0 Csaba Kiraly
                                        if(vcopy) {
786
                                                video_frame_size = packet.size;
787
                                                if (video_frame_size > video_outbuf_size) {
788
                                                        fprintf(stderr, "VIDEO: error, outbuf too small, SKIPPING\n");;
789 0fe99630 Csaba Kiraly
                                                        av_free_packet(&packet);
790 b9477cd0 Csaba Kiraly
                                                        continue;
791
                                                } else {
792
                                                        memcpy(video_outbuf, packet.data, video_frame_size);
793
                                                }
794 77b68cb7 napawine
795
                                                if (pFrame->pkt_pts != AV_NOPTS_VALUE) {
796
                                                        target_pts = pFrame->pkt_pts;
797
                                                }else {        //TODO: review this
798
                                                        target_pts = pFrame->pkt_dts;
799
                                                }
800 f6580287 napawine
                                        } else {
801
802
                                            if (pFrame->pkt_pts != AV_NOPTS_VALUE) {
803
                                                pFrame->pts = av_rescale_q(pFrame->pkt_pts, pFormatCtx->streams[videoStream]->time_base, pCodecCtxEnc->time_base);
804
                                            } else {        //try to figure out the pts //TODO: review this
805
                                                if (pFrame->pkt_dts != AV_NOPTS_VALUE) {
806
                                                        pFrame->pts = av_rescale_q(pFrame->pkt_dts, pFormatCtx->streams[videoStream]->time_base, pCodecCtxEnc->time_base);
807
                                                }
808
                                            }
809
810 51d67a10 Csaba Kiraly
#ifdef USE_AVFILTER
811
                                        //apply avfilters
812
                                        filter(pFrame,pFrame2);
813
                                        pFrame = pFrame2;
814 795fe885 Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode: pkt_dts %"PRId64" pkt_pts %"PRId64" frame.pts %"PRId64"\n", pFrame2->pkt_dts, pFrame2->pkt_pts, pFrame2->pts);
815 51d67a10 Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode intype %d%s\n", pFrame2->pict_type, pFrame2->key_frame ? " (key)" : "");
816
#endif
817
818 f6580287 napawine
                                            if(pCodecCtx->height != pCodecCtxEnc->height || pCodecCtx->width != pCodecCtxEnc->width) {
819 31db59aa Csaba Kiraly
//                                                static AVPicture pict;
820 e11386c0 CsabaKiraly
                                                static struct SwsContext *img_convert_ctx = NULL;
821
                                                
822 0831ad06 Csaba Kiraly
                                                pFrame->pict_type = 0;
823 e11386c0 CsabaKiraly
                                                if(img_convert_ctx == NULL)
824
                                                {
825 387b789d Csaba Kiraly
                                                        img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, dest_width, dest_height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
826 e11386c0 CsabaKiraly
                                                        if(img_convert_ctx == NULL) {
827
                                                                fprintf(stderr, "Cannot initialize the conversion context!\n");
828
                                                                exit(1);
829
                                                        }
830
                                                }
831
                                                sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, scaledFrame->data, scaledFrame->linesize);
832 9918580a napawine
                                                scaledFrame->pts = pFrame->pts;
833
                                                scaledFrame->pict_type = 0;
834 e11386c0 CsabaKiraly
                                                video_frame_size = avcodec_encode_video(pCodecCtxEnc, video_outbuf, video_outbuf_size, scaledFrame);
835 f6580287 napawine
                                            } else {
836 0831ad06 Csaba Kiraly
                                                pFrame->pict_type = 0;
837 e11386c0 CsabaKiraly
                                                video_frame_size = avcodec_encode_video(pCodecCtxEnc, video_outbuf, video_outbuf_size, pFrame);
838 f6580287 napawine
                                            }
839
840
                                            //use pts if dts is invalid
841
                                            if(pCodecCtxEnc->coded_frame->pts!=AV_NOPTS_VALUE)
842
                                                target_pts = av_rescale_q(pCodecCtxEnc->coded_frame->pts, pCodecCtxEnc->time_base, pFormatCtx->streams[videoStream]->time_base);
843
                                            else {        //TODO: review this
844
                                                av_free_packet(&packet);
845
                                                continue;
846
                                                //fprintf(stderr, "VIDEOout: pts error\n");
847
                                                //exit(1);
848
                                            }
849 0831ad06 Csaba Kiraly
                                        }
850
851 69fd123e GiuseppeTropea
                                        if(video_frame_size <= 0)
852 e11386c0 CsabaKiraly
                                        {
853
                                                contFrameVideo = STREAMER_MAX(contFrameVideo-1, 0);
854 0fe99630 Csaba Kiraly
                                                av_free_packet(&packet);
855 69fd123e GiuseppeTropea
                                                continue;
856 e11386c0 CsabaKiraly
                                        }
857 e810bf7b GiuseppeTropea
858 b9477cd0 Csaba Kiraly
                                        if(!vcopy && pCodecCtxEnc->coded_frame) {
859 795fe885 Csaba Kiraly
                                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOout: pkt_dts %"PRId64" pkt_pts %"PRId64" frame.pts %"PRId64"\n", pCodecCtxEnc->coded_frame->pkt_dts, pCodecCtxEnc->coded_frame->pkt_pts, pCodecCtxEnc->coded_frame->pts);
860 290b7b8c Csaba Kiraly
                                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOout: outtype: %d%s\n", pCodecCtxEnc->coded_frame->pict_type, pCodecCtxEnc->coded_frame->key_frame ? " (key)" : "");
861 9235dfb8 GiuseppeTropea
                                        }
862
#ifdef DISPLAY_PSNR
863
                                        static double ist_psnr = 0;
864
                                        static double cum_psnr = 0;
865
                                        static int psnr_samples = 0;
866
                                        if(!vcopy && pCodecCtxEnc->coded_frame) {
867
                                                if(pCodecCtxEnc->flags&CODEC_FLAG_PSNR) {
868
                                                        ist_psnr = GET_PSNR(pCodecCtxEnc->coded_frame->error[0]/(pCodecCtxEnc->width*pCodecCtxEnc->height*255.0*255.0));
869
                                                        psnr_samples++;
870
                                                        cum_psnr += ist_psnr;
871
                                                        fprintf(stderr, "PSNR: ist %.4f avg: %.4f\n", ist_psnr, cum_psnr / (double)psnr_samples);
872
                                                }
873 3e0c28b0 CsabaKiraly
                                        }
874
#endif
875
876 b98fce85 Csaba Kiraly
                                        if(offset_av)
877 34149271 GiuseppeTropea
                                        {
878 efd33edc Csaba Kiraly
                                                if(FirstTimeVideo && target_pts>0) {
879 2018e261 Csaba Kiraly
                                                        ptsvideo1 = target_pts;
880 34149271 GiuseppeTropea
                                                        FirstTimeVideo = 0;
881 795fe885 Csaba Kiraly
                                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: SET PTS BASE OFFSET %"PRId64"\n", ptsvideo1);
882 34149271 GiuseppeTropea
                                                }
883
                                        }
884 7ea4a367 GiuseppeTropea
                                        else //we want to compensate audio and video offset for this source
885 34149271 GiuseppeTropea
                                        {
886 efd33edc Csaba Kiraly
                                                if(FirstTimeVideo && target_pts>0) {
887 34149271 GiuseppeTropea
                                                        //maintain the offset between audio pts and video pts
888
                                                        //because in case of live source they have the same numbering
889
                                                        if(ptsaudio1 > 0) //if we have already seen some audio frames...
890
                                                                ptsvideo1 = ptsaudio1;
891
                                                        else
892 2018e261 Csaba Kiraly
                                                                ptsvideo1 = target_pts;
893 34149271 GiuseppeTropea
                                                        FirstTimeVideo = 0;
894 795fe885 Csaba Kiraly
                                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO LIVE: SET PTS BASE OFFSET %"PRId64"\n", ptsvideo1);
895 34149271 GiuseppeTropea
                                                }
896 4c879040 GiuseppeTropea
                                        }
897
                                        //compute the new video timestamp in milliseconds
898
                                        if(frame->number>0) {
899 6291b208 Csaba Kiraly
                                                newTime = (target_pts - ptsvideo1) * 1000 * pFormatCtx->streams[videoStream]->time_base.num / pFormatCtx->streams[videoStream]->time_base.den;
900 0452f734 GiuseppeTropea
                                                // store timestamp in useconds for next frame sleep
901
                                                newTime_video = newTime*1000;
902 11e39d44 GiuseppeTropea
                                        }
903 795fe885 Csaba Kiraly
                                        dcprintf(DEBUG_TIMESTAMPING, "VIDEO: NEWTIMESTAMP %lld\n", newTime);
904 34149271 GiuseppeTropea
                                        if(newTime<0) {
905 290b7b8c Csaba Kiraly
                                                dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: SKIPPING FRAME\n");
906 df2ad829 GiuseppeTropea
                                                newtime_anomalies_counter++;
907 290b7b8c Csaba Kiraly
                                                dcprintf(DEBUG_ANOMALIES, "READLOOP: NEWTIME negative video timestamp anomaly detected number %d\n", newtime_anomalies_counter);
908 e11386c0 CsabaKiraly
                                                contFrameVideo = STREAMER_MAX(contFrameVideo-1, 0);
909 0fe99630 Csaba Kiraly
                                                av_free_packet(&packet);
910 34149271 GiuseppeTropea
                                                continue; //SKIP THIS FRAME, bad timestamp
911
                                        }
912 e11386c0 CsabaKiraly
                                        
913 795fe885 Csaba Kiraly
                                        //~ printf("pCodecCtxEnc->error[0]=%"PRId64"\n", pFrame->error[0]);
914 e810bf7b GiuseppeTropea
        
915
                                        frame->timestamp.tv_sec = (long long)newTime/1000;
916 11e39d44 GiuseppeTropea
                                        frame->timestamp.tv_usec = newTime%1000;
917 648357d7 GiuseppeTropea
                                        frame->size = video_frame_size;
918 0452f734 GiuseppeTropea
                                        /* pict_type maybe 1 (I), 2 (P), 3 (B), 5 (AUDIO)*/
919 b9477cd0 Csaba Kiraly
                                        frame->type = vcopy ? pFrame->pict_type : (unsigned char)pCodecCtxEnc->coded_frame->pict_type;
920 e11386c0 CsabaKiraly
921 290b7b8c Csaba Kiraly
                                        if (!vcopy) dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: original codec frame number %d vs. encoded %d vs. packed %d\n", pCodecCtx->frame_number, pCodecCtxEnc->frame_number, frame->number);
922
                                        if (!vcopy) dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: duration %d timebase %d %d container timebase %d\n", (int)packet.duration, pCodecCtxEnc->time_base.den, pCodecCtxEnc->time_base.num, pCodecCtx->time_base.den);
923 e11386c0 CsabaKiraly
924
#ifdef YUV_RECORD_ENABLED
925 b9477cd0 Csaba Kiraly
                                        if(!vcopy && ChunkerStreamerTestMode)
926 e11386c0 CsabaKiraly
                                        {
927
                                                if(videotrace)
928
                                                        fprintf(videotrace, "%d %d %d\n", frame->number, pFrame->pict_type, frame->size);
929
930
                                                if(pCodecCtx->height != pCodecCtxEnc->height || pCodecCtx->width != pCodecCtxEnc->width)
931 387b789d Csaba Kiraly
                                                        SaveFrame(scaledFrame, dest_width, dest_height);
932 e11386c0 CsabaKiraly
                                                else
933 387b789d Csaba Kiraly
                                                        SaveFrame(pFrame, dest_width, dest_height);
934 e11386c0 CsabaKiraly
935
                                                ++savedVideoFrames;
936
                                                SaveEncodedFrame(frame, video_outbuf);
937
938
                                                if(!firstSavedVideoFrame)
939
                                                        firstSavedVideoFrame = frame->number;
940
                                                
941
                                                char tmp_filename[255];
942
                                                sprintf(tmp_filename, "yuv_data/streamer_out_context.txt");
943
                                                FILE* tmp = fopen(tmp_filename, "w");
944
                                                if(tmp)
945
                                                {
946 31db59aa Csaba Kiraly
                                                        fprintf(tmp, "width = %d\nheight = %d\ntotal_frames_saved = %d\ntotal_frames_decoded = %d\nfirst_frame_number = %ld\nlast_frame_number = %d\n"
947 387b789d Csaba Kiraly
                                                                ,dest_width, dest_height
948 e11386c0 CsabaKiraly
                                                                ,savedVideoFrames, savedVideoFrames, firstSavedVideoFrame, frame->number);
949
                                                        fclose(tmp);
950
                                                }
951
                                        }
952
#endif
953
954 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: encapsulated frame size:%d type:%d\n", frame->size, frame->type);
955 795fe885 Csaba Kiraly
                                        dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: timestamped sec %ld usec:%ld\n", (long)frame->timestamp.tv_sec, (long)frame->timestamp.tv_usec);
956 e11386c0 CsabaKiraly
                                        //contFrameVideo++; //lets increase the numbering of the frames
957 e810bf7b GiuseppeTropea
958 648357d7 GiuseppeTropea
                                        if(update_chunk(chunk, frame, video_outbuf) == -1) {
959
                                                fprintf(stderr, "VIDEO: unable to update chunk %d. Exiting.\n", chunk->seq);
960
                                                exit(-1);
961 11e39d44 GiuseppeTropea
                                        }
962 648357d7 GiuseppeTropea
963 e11386c0 CsabaKiraly
                                        if(chunkFilled(chunk, VIDEO_CHUNK)) { // is chunk filled using current strategy?
964 e3503a45 Csaba Kiraly
                                                //calculate priority
965
                                                chunk->priority /= chunk->frames_num;
966
967 11e39d44 GiuseppeTropea
                                                //SAVE ON FILE
968 34149271 GiuseppeTropea
                                                //saveChunkOnFile(chunk);
969 03590124 Csaba Kiraly
                                                //Send the chunk to an external transport/player
970
                                                sendChunk(chunk);
971 eb1ba2c5 Csaba Kiraly
                                                dctprintf(DEBUG_CHUNKER, "VIDEO: sent chunk video %d, prio:%f, size %d\n", chunk->seq, chunk->priority, chunk->len);
972 269f1314 GiuseppeTropea
                                                chunk->seq = 0; //signal that we need an increase
973
                                                //initChunk(chunk, &seq_current_chunk);
974 11e39d44 GiuseppeTropea
                                        }
975 0452f734 GiuseppeTropea
976
                                        //compute how long it took to encode video frame
977
                                        gettimeofday(&now_tv, NULL);
978
                                        long long usec = (now_tv.tv_sec-tmp_tv.tv_sec)*1000000;
979
                                        usec+=(now_tv.tv_usec-tmp_tv.tv_usec);
980
                                        if(usec > maxVDecodeTime)
981
                                                maxVDecodeTime = usec;
982
983
                                        //we DONT have an audio track, so we compute timings and determine
984
                                        //how much time we have to sleep at next VIDEO frame taking
985
                                        //also into account how much time was needed to encode the current
986
                                        //video frame
987
                                        //all this in case the video source is not live, i.e. not self-timing
988
                                        //and only in case there is no audio track
989
                                        if(audioStream == -1) {
990
                                                if(!live_source) {
991
                                                        if(newTime_prev != 0) {
992
                                                                //how much delay between video frames ideally
993
                                                                long long maxDelay = newTime_video - newTime_prev;
994
                                                                sleep = (maxDelay - usec);
995 290b7b8c Csaba Kiraly
                                                                dcprintf(DEBUG_ANOMALIES,"\tmaxDelay=%ld\n", ((long)maxDelay));
996
                                                                dcprintf(DEBUG_ANOMALIES,"\tlast video frame interval=%ld; sleep time=%ld\n", ((long)usec), ((long)sleep));
997 0452f734 GiuseppeTropea
                                                        }
998
                                                        else
999
                                                                sleep = 0;
1000
1001
                                                        //update and store counters
1002
                                                        newTime_prev = newTime_video;
1003
1004
                                                        //i can also sleep now instead of at the beginning of
1005
                                                        //the next frame because in this case we only have video
1006
                                                        //frames, hence it would immediately be the next thing to do
1007
                                                        if(sleep > 0) {
1008 290b7b8c Csaba Kiraly
                                                                dcprintf(DEBUG_ANOMALIES, "\n\tREADLOOP: going to sleep for %ld microseconds\n", sleep);
1009 0452f734 GiuseppeTropea
                                                                usleep(sleep);
1010
                                                        }
1011
1012
                                                }
1013
                                        }
1014
1015 11e39d44 GiuseppeTropea
                                }
1016
                        }
1017
                }
1018 69fd123e GiuseppeTropea
                else if(packet.stream_index==audioStream)
1019
                {
1020
                        if(sleep > 0)
1021
                        {
1022 290b7b8c Csaba Kiraly
                                dcprintf(DEBUG_ANOMALIES, "\n\tREADLOOP: going to sleep for %ld microseconds\n", sleep);
1023 69fd123e GiuseppeTropea
                                usleep(sleep);
1024
                        }
1025
                        
1026 648357d7 GiuseppeTropea
                        audio_data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1027
                        //decode the audio packet into a raw audio source buffer
1028 69fd123e GiuseppeTropea
                        if(avcodec_decode_audio3(aCodecCtx, samples, &audio_data_size, &packet)>0)
1029
                        {
1030 290b7b8c Csaba Kiraly
                                dcprintf(DEBUG_AUDIO_FRAMES, "\n-------AUDIO FRAME\n");
1031
                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: newTimeaudioSTART : %lf\n", (double)(packet.pts)*av_q2d(pFormatCtx->streams[audioStream]->time_base));
1032 648357d7 GiuseppeTropea
                                if(audio_data_size>0) {
1033 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: datasizeaudio:%d\n", audio_data_size);
1034 e810bf7b GiuseppeTropea
                                        /* if a frame has been decoded, output it */
1035 648357d7 GiuseppeTropea
                                        //fwrite(samples, 1, audio_data_size, outfileaudio);
1036 11e39d44 GiuseppeTropea
                                }
1037 0fe99630 Csaba Kiraly
                                else {
1038
                                        av_free_packet(&packet);
1039 34149271 GiuseppeTropea
                                        continue;
1040 0fe99630 Csaba Kiraly
                                }
1041 e810bf7b GiuseppeTropea
        
1042 648357d7 GiuseppeTropea
                                audio_frame_size = avcodec_encode_audio(aCodecCtxEnc, audio_outbuf, audio_data_size, samples);
1043 0fe99630 Csaba Kiraly
                                if(audio_frame_size <= 0) {
1044
                                        av_free_packet(&packet);
1045 69fd123e GiuseppeTropea
                                        continue;
1046 0fe99630 Csaba Kiraly
                                }
1047 69fd123e GiuseppeTropea
                                
1048 34149271 GiuseppeTropea
                                frame->number = contFrameAudio;
1049
1050 e810bf7b GiuseppeTropea
                                if(frame->number==0) {
1051 0fe99630 Csaba Kiraly
                                        if(packet.dts==AV_NOPTS_VALUE) {
1052
                                                av_free_packet(&packet);
1053 e810bf7b GiuseppeTropea
                                                continue;
1054 0fe99630 Csaba Kiraly
                                        }
1055 e810bf7b GiuseppeTropea
                                        last_pkt_dts_audio = packet.dts;
1056
                                        newTime = 0;
1057
                                }
1058
                                else {
1059
                                        if(packet.dts!=AV_NOPTS_VALUE) {
1060
                                                delta_audio = packet.dts-last_pkt_dts_audio;
1061
                                                last_pkt_dts_audio = packet.dts;
1062
                                        }
1063 0fe99630 Csaba Kiraly
                                        else if(delta_audio==0) {
1064
                                                av_free_packet(&packet);
1065 e810bf7b GiuseppeTropea
                                                continue;
1066 0fe99630 Csaba Kiraly
                                        }
1067 e810bf7b GiuseppeTropea
                                }
1068 290b7b8c Csaba Kiraly
                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: original codec frame number %d vs. encoded %d vs. packed %d\n", aCodecCtx->frame_number, aCodecCtxEnc->frame_number, frame->number);
1069 34149271 GiuseppeTropea
                                //use pts if dts is invalid
1070
                                if(packet.dts!=AV_NOPTS_VALUE)
1071
                                        target_pts = packet.dts;
1072 0fe99630 Csaba Kiraly
                                else if(packet.pts!=AV_NOPTS_VALUE) {
1073 34149271 GiuseppeTropea
                                        target_pts = packet.pts;
1074 0fe99630 Csaba Kiraly
                                } else  {
1075
                                        av_free_packet(&packet);
1076 34149271 GiuseppeTropea
                                        continue;
1077 0fe99630 Csaba Kiraly
                                }
1078 34149271 GiuseppeTropea
1079 b98fce85 Csaba Kiraly
                                if(offset_av)
1080 34149271 GiuseppeTropea
                                {
1081 eb0c9035 GiuseppeTropea
                                        if(FirstTimeAudio && packet.dts>0) {
1082 2018e261 Csaba Kiraly
                                                ptsaudio1 = packet.dts;
1083 34149271 GiuseppeTropea
                                                FirstTimeAudio = 0;
1084 795fe885 Csaba Kiraly
                                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: SET PTS BASE OFFSET %"PRId64"\n", ptsaudio1);
1085 34149271 GiuseppeTropea
                                        }
1086 1e69ae95 GiuseppeTropea
                                }
1087 7ea4a367 GiuseppeTropea
                                else //we want to compensate audio and video offset for this source
1088 34149271 GiuseppeTropea
                                {
1089 eb0c9035 GiuseppeTropea
                                        if(FirstTimeAudio && packet.dts>0) {
1090 34149271 GiuseppeTropea
                                                //maintain the offset between audio pts and video pts
1091
                                                //because in case of live source they have the same numbering
1092
                                                if(ptsvideo1 > 0) //if we have already seen some video frames...
1093
                                                        ptsaudio1 = ptsvideo1;
1094
                                                else
1095 2018e261 Csaba Kiraly
                                                        ptsaudio1 = packet.dts;
1096 34149271 GiuseppeTropea
                                                FirstTimeAudio = 0;
1097 795fe885 Csaba Kiraly
                                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO LIVE: SET PTS BASE OFFSET %"PRId64"\n", ptsaudio1);
1098 34149271 GiuseppeTropea
                                        }
1099 4c879040 GiuseppeTropea
                                }
1100
                                //compute the new audio timestamps in milliseconds
1101
                                if(frame->number>0) {
1102 2018e261 Csaba Kiraly
                                        newTime = ((target_pts-ptsaudio1)*1000.0*((double)av_q2d(pFormatCtx->streams[audioStream]->time_base)));//*(double)delta_audio;
1103 69fd123e GiuseppeTropea
                                        // store timestamp in useconds for next frame sleep
1104
                                        newTime_audio = newTime*1000;
1105 34149271 GiuseppeTropea
                                }
1106 795fe885 Csaba Kiraly
                                dcprintf(DEBUG_TIMESTAMPING, "AUDIO: NEWTIMESTAMP %lld\n", newTime);
1107 34149271 GiuseppeTropea
                                if(newTime<0) {
1108 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: SKIPPING FRAME\n");
1109 df2ad829 GiuseppeTropea
                                        newtime_anomalies_counter++;
1110 290b7b8c Csaba Kiraly
                                        dcprintf(DEBUG_ANOMALIES, "READLOOP: NEWTIME negative audio timestamp anomaly detected number %d\n", newtime_anomalies_counter);
1111 0fe99630 Csaba Kiraly
                                        av_free_packet(&packet);
1112 34149271 GiuseppeTropea
                                        continue; //SKIP THIS FRAME, bad timestamp
1113
                                }
1114 e810bf7b GiuseppeTropea
1115 80515685 Csaba Kiraly
                                frame->timestamp.tv_sec = (unsigned int)(newTime + delay_audio)/1000;
1116
                                frame->timestamp.tv_usec = (newTime + delay_audio)%1000;
1117 648357d7 GiuseppeTropea
                                frame->size = audio_frame_size;
1118
                                frame->type = 5; // 5 is audio type
1119 795fe885 Csaba Kiraly
                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: pts %"PRId64" duration %d timebase %d %d dts %"PRId64"\n", packet.pts, packet.duration, pFormatCtx->streams[audioStream]->time_base.num, pFormatCtx->streams[audioStream]->time_base.den, packet.dts);
1120
                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: timestamp sec:%ld usec:%ld\n", (long)frame->timestamp.tv_sec, (long)frame->timestamp.tv_usec);
1121
                                dcprintf(DEBUG_AUDIO_FRAMES, "AUDIO: deltaaudio %"PRId64"\n", delta_audio);        
1122 34149271 GiuseppeTropea
                                contFrameAudio++;
1123
1124 648357d7 GiuseppeTropea
                                if(update_chunk(chunkaudio, frame, audio_outbuf) == -1) {
1125
                                        fprintf(stderr, "AUDIO: unable to update chunk %d. Exiting.\n", chunkaudio->seq);
1126
                                        exit(-1);
1127
                                }
1128 34149271 GiuseppeTropea
                                //set priority
1129 11e39d44 GiuseppeTropea
                                chunkaudio->priority = 1;
1130 34149271 GiuseppeTropea
1131 e11386c0 CsabaKiraly
                                if(chunkFilled(chunkaudio, AUDIO_CHUNK)) {
1132 0452f734 GiuseppeTropea
                                        // is chunk filled using current strategy?
1133
                                        //SAVE ON FILE
1134
                                        //saveChunkOnFile(chunkaudio);
1135 03590124 Csaba Kiraly
                                        //Send the chunk to an external transport/player
1136
                                        sendChunk(chunkaudio);
1137 eb1ba2c5 Csaba Kiraly
                                        dctprintf(DEBUG_CHUNKER, "AUDIO: just sent chunk audio %d\n", chunkaudio->seq);
1138 0452f734 GiuseppeTropea
                                        chunkaudio->seq = 0; //signal that we need an increase
1139
                                        //initChunk(chunkaudio, &seq_current_chunk);
1140
                                }
1141
1142
                                //we have an audio track, so we compute timings and determine
1143
                                //how much time we have to sleep at next audio frame taking
1144
                                //also into account how much time was needed to encode the
1145
                                //video frames
1146
                                //all this in case the video source is not live, i.e. not self-timing
1147
                                if(!live_source)
1148 69fd123e GiuseppeTropea
                                {
1149 0452f734 GiuseppeTropea
                                        if(newTime_prev != 0)
1150 69fd123e GiuseppeTropea
                                        {
1151 0452f734 GiuseppeTropea
                                                long long maxDelay = newTime_audio - newTime_prev;
1152 69fd123e GiuseppeTropea
1153 0452f734 GiuseppeTropea
                                                gettimeofday(&now_tv, NULL);
1154
                                                long long usec = (now_tv.tv_sec-lastAudioSent.tv_sec)*1000000;
1155
                                                usec+=(now_tv.tv_usec-lastAudioSent.tv_usec);
1156 69fd123e GiuseppeTropea
1157 0452f734 GiuseppeTropea
                                                if(usec > maxAudioInterval)
1158
                                                        maxAudioInterval = usec;
1159 69fd123e GiuseppeTropea
1160 0452f734 GiuseppeTropea
                                                lateTime -= (maxDelay - usec);
1161 290b7b8c Csaba Kiraly
                                                dcprintf(DEBUG_ANOMALIES,"\tmaxDelay=%ld, maxAudioInterval=%ld\n", ((long)maxDelay), ((long) maxAudioInterval));
1162
                                                dcprintf(DEBUG_ANOMALIES,"\tlast audio frame interval=%ld; lateTime=%ld\n", ((long)usec), ((long)lateTime));
1163 69fd123e GiuseppeTropea
1164 0452f734 GiuseppeTropea
                                                if((lateTime+maxAudioInterval) < 0)
1165
                                                        sleep = (lateTime+maxAudioInterval)*-1;
1166 69fd123e GiuseppeTropea
                                                else
1167
                                                        sleep = 0;
1168
                                        }
1169 0452f734 GiuseppeTropea
                                        else
1170
                                                sleep = 0;
1171
1172
                                        newTime_prev = newTime_audio;
1173
                                        gettimeofday(&lastAudioSent, NULL);
1174 1e69ae95 GiuseppeTropea
                                }
1175
                        }
1176
                }
1177 290b7b8c Csaba Kiraly
                dcprintf(DEBUG_CHUNKER,"Free the packet that was allocated by av_read_frame\n");
1178 d25320f1 Csaba Kiraly
                av_free_packet(&packet);
1179 1e69ae95 GiuseppeTropea
        }
1180 e11386c0 CsabaKiraly
        
1181
        if(videotrace)
1182
                fclose(videotrace);
1183
        if(psnrtrace)
1184
                fclose(psnrtrace);
1185 1e69ae95 GiuseppeTropea
1186 df2ad829 GiuseppeTropea
close:
1187 7ea4a367 GiuseppeTropea
        if(chunk->seq != 0 && chunk->frames_num>0) {
1188 1e69ae95 GiuseppeTropea
                //SAVE ON FILE
1189 34149271 GiuseppeTropea
                //saveChunkOnFile(chunk);
1190 03590124 Csaba Kiraly
                //Send the chunk to an external transport/player
1191
                sendChunk(chunk);
1192 290b7b8c Csaba Kiraly
                dcprintf(DEBUG_CHUNKER, "CHUNKER: SENDING LAST VIDEO CHUNK\n");
1193 a573b3de GiuseppeTropea
                chunk->seq = 0; //signal that we need an increase just in case we will restart
1194 1e69ae95 GiuseppeTropea
        }
1195 7ea4a367 GiuseppeTropea
        if(chunkaudio->seq != 0 && chunkaudio->frames_num>0) {
1196 a573b3de GiuseppeTropea
                //SAVE ON FILE     
1197 34149271 GiuseppeTropea
                //saveChunkOnFile(chunkaudio);
1198
                //Send the chunk via http to an external transport/player
1199 03590124 Csaba Kiraly
                sendChunk(chunkaudio);
1200 290b7b8c Csaba Kiraly
                dcprintf(DEBUG_CHUNKER, "CHUNKER: SENDING LAST AUDIO CHUNK\n");
1201 a573b3de GiuseppeTropea
                chunkaudio->seq = 0; //signal that we need an increase just in case we will restart
1202 1e69ae95 GiuseppeTropea
        }
1203
1204 e11386c0 CsabaKiraly
#ifdef HTTPIO
1205 34149271 GiuseppeTropea
        /* finalize the HTTP chunk pusher */
1206 8de6681e GiuseppeTropea
        finalizeChunkPusher();
1207 e11386c0 CsabaKiraly
#endif
1208 1e69ae95 GiuseppeTropea
1209
        free(chunk);
1210
        free(chunkaudio);
1211
        free(frame);
1212 648357d7 GiuseppeTropea
        av_free(video_outbuf);
1213 e11386c0 CsabaKiraly
        av_free(scaledFrame_buffer);
1214 648357d7 GiuseppeTropea
        av_free(audio_outbuf);
1215 34149271 GiuseppeTropea
        free(cmeta);
1216 1e69ae95 GiuseppeTropea
1217
        // Free the YUV frame
1218 51d67a10 Csaba Kiraly
        av_free(pFrame1);
1219
        av_free(pFrame2);
1220 e11386c0 CsabaKiraly
        av_free(scaledFrame);
1221 648357d7 GiuseppeTropea
        av_free(samples);
1222 1e69ae95 GiuseppeTropea
  
1223
        // Close the codec
1224 b9477cd0 Csaba Kiraly
        if (!vcopy) avcodec_close(pCodecCtx);
1225
        if (!vcopy) avcodec_close(pCodecCtxEnc);
1226 1e69ae95 GiuseppeTropea
1227
        if(audioStream!=-1) {
1228
                avcodec_close(aCodecCtx);
1229
                avcodec_close(aCodecCtxEnc);
1230
        }
1231
  
1232
        // Close the video file
1233
        av_close_input_file(pFormatCtx);
1234 ac723195 GiuseppeTropea
1235 0864b2dc GiuseppeTropea
        if(LOOP_MODE) {
1236
                //we want video to continue, but the av_read_frame stopped
1237 ac723195 GiuseppeTropea
                //lets wait a 5 secs, and cycle in again
1238
                usleep(5000000);
1239 290b7b8c Csaba Kiraly
                dcprintf(DEBUG_CHUNKER, "CHUNKER: WAITING 5 secs FOR LIVE SOURCE TO SKIP ERRORS AND RESTARTING\n");
1240 ac723195 GiuseppeTropea
                videoStream = -1;
1241
                audioStream = -1;
1242
                FirstTimeAudio=1;
1243
                FirstTimeVideo=1;
1244
                pts_anomalies_counter=0;
1245 df2ad829 GiuseppeTropea
                newtime_anomalies_counter=0;
1246 ac723195 GiuseppeTropea
                newTime=0;
1247 69fd123e GiuseppeTropea
                newTime_audio=0;
1248 ac723195 GiuseppeTropea
                newTime_prev=0;
1249 2018e261 Csaba Kiraly
                ptsvideo1=0;
1250
                ptsaudio1=0;
1251 ac723195 GiuseppeTropea
                last_pkt_dts=0;
1252
                delta_video=0;
1253
                delta_audio=0;
1254
                last_pkt_dts_audio=0;
1255
                target_pts=0;
1256
                i=0;
1257 e11386c0 CsabaKiraly
                //~ contFrameVideo = 0;
1258
                //~ contFrameAudio = 1;
1259
                
1260
#ifdef YUV_RECORD_ENABLED
1261
                if(ChunkerStreamerTestMode)
1262
                {
1263
                        video_record_count++;
1264
                        //~ savedVideoFrames = 0;
1265
                        
1266
                        //~ char tmp_filename[255];
1267
                        //~ sprintf(tmp_filename, "yuv_data/out_%d.yuv", video_record_count);
1268
                        //~ FILE *pFile=fopen(tmp_filename, "w");
1269
                        //~ if(pFile!=NULL)
1270
                                //~ fclose(pFile);
1271
                }
1272
#endif
1273
1274 ac723195 GiuseppeTropea
                goto restart;
1275
        }
1276
1277 f220e463 Csaba Kiraly
#ifdef TCPIO
1278
        finalizeTCPChunkPusher();
1279
#endif
1280
1281 51d67a10 Csaba Kiraly
#ifdef USE_AVFILTER
1282
        close_filters();
1283
#endif
1284
1285 1e69ae95 GiuseppeTropea
        return 0;
1286
}
1287 648357d7 GiuseppeTropea
1288
int update_chunk(ExternalChunk *chunk, Frame *frame, uint8_t *outbuf) {
1289 8b52d5cf GiuseppeTropea
        //the frame.h gets encoded into 5 slots of 32bits (3 ints plus 2 more for the timeval struct
1290
        static int sizeFrameHeader = 5*sizeof(int32_t);
1291 648357d7 GiuseppeTropea
1292
        //moving temp pointer to encode Frame on the wire
1293
        uint8_t *tempdata = NULL;
1294
1295 269f1314 GiuseppeTropea
        if(chunk->seq == 0) {
1296
                initChunk(chunk, &seq_current_chunk);
1297
        }
1298 e3503a45 Csaba Kiraly
        //add frame priority to chunk priority (to be normalized later on)
1299
        chunk->priority += frame->type + 1; // I:2, P:3, B:4
1300
1301 648357d7 GiuseppeTropea
        //HINT on malloc
1302
        chunk->data = (uint8_t *)realloc(chunk->data, sizeof(uint8_t)*(chunk->payload_len + frame->size + sizeFrameHeader));
1303
        if(!chunk->data)  {
1304
                fprintf(stderr, "Memory error in chunk!!!\n");
1305
                return -1;
1306
        }
1307
        chunk->frames_num++; // number of frames in the current chunk
1308
1309 8b52d5cf GiuseppeTropea
/*
1310 648357d7 GiuseppeTropea
        //package the Frame header
1311
        tempdata = chunk->data+chunk->payload_len;
1312
        *((int32_t *)tempdata) = frame->number;
1313
        tempdata+=sizeof(int32_t);
1314
        *((struct timeval *)tempdata) = frame->timestamp;
1315
        tempdata+=sizeof(struct timeval);
1316
        *((int32_t *)tempdata) = frame->size;
1317
        tempdata+=sizeof(int32_t);
1318
        *((int32_t *)tempdata) = frame->type;
1319
        tempdata+=sizeof(int32_t);
1320 8b52d5cf GiuseppeTropea
*/
1321
        //package the Frame header: network order and platform independent
1322
        tempdata = chunk->data+chunk->payload_len;
1323
        bit32_encoded_push(frame->number, tempdata);
1324
        bit32_encoded_push(frame->timestamp.tv_sec, tempdata + CHUNK_TRANSCODING_INT_SIZE);
1325
        bit32_encoded_push(frame->timestamp.tv_usec, tempdata + CHUNK_TRANSCODING_INT_SIZE*2);
1326
        bit32_encoded_push(frame->size, tempdata + CHUNK_TRANSCODING_INT_SIZE*3);
1327
        bit32_encoded_push(frame->type, tempdata + CHUNK_TRANSCODING_INT_SIZE*4);
1328 648357d7 GiuseppeTropea
1329
         //insert the new frame data
1330
        memcpy(chunk->data + chunk->payload_len + sizeFrameHeader, outbuf, frame->size);
1331
        chunk->payload_len += frame->size + sizeFrameHeader; // update payload length
1332 8b52d5cf GiuseppeTropea
        //chunk lenght is updated just prior to pushing it out because
1333
        //the chunk header len is better calculated there
1334
        //chunk->len = sizeChunkHeader + chunk->payload_len; // update overall length
1335 648357d7 GiuseppeTropea
1336
        //update timestamps
1337
        if(((int)frame->timestamp.tv_sec < (int)chunk->start_time.tv_sec) || ((int)frame->timestamp.tv_sec==(int)chunk->start_time.tv_sec && (int)frame->timestamp.tv_usec < (int)chunk->start_time.tv_usec) || (int)chunk->start_time.tv_sec==-1) {
1338
                                                chunk->start_time.tv_sec = frame->timestamp.tv_sec;
1339
                                                chunk->start_time.tv_usec = frame->timestamp.tv_usec;
1340
        }
1341
        
1342
        if(((int)frame->timestamp.tv_sec > (int)chunk->end_time.tv_sec) || ((int)frame->timestamp.tv_sec==(int)chunk->end_time.tv_sec && (int)frame->timestamp.tv_usec > (int)chunk->end_time.tv_usec) || (int)chunk->end_time.tv_sec==-1) {
1343
                                                chunk->end_time.tv_sec = frame->timestamp.tv_sec;
1344
                                                chunk->end_time.tv_usec = frame->timestamp.tv_usec;
1345
        }
1346
        return 0;
1347
}
1348
1349 e11386c0 CsabaKiraly
void SaveFrame(AVFrame *pFrame, int width, int height)
1350
{
1351
        FILE *pFile;
1352
        int  y;
1353
1354
         // Open file
1355
        char tmp_filename[255];
1356
        sprintf(tmp_filename, "yuv_data/streamer_out.yuv");
1357
        pFile=fopen(tmp_filename, "ab");
1358
        if(pFile==NULL)
1359
                return;
1360
1361
        // Write header
1362
        //fprintf(pFile, "P5\n%d %d\n255\n", width, height);
1363
  
1364
        // Write Y data
1365
        for(y=0; y<height; y++)
1366
                  if(fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width, pFile) != width)
1367
                {
1368
                        printf("errno = %d\n", errno);
1369
                        exit(1);
1370
                }
1371
        // Write U data
1372
        for(y=0; y<height/2; y++)
1373
                  if(fwrite(pFrame->data[1]+y*pFrame->linesize[1], 1, width/2, pFile) != width/2)
1374
                  {
1375
                        printf("errno = %d\n", errno);
1376
                        exit(1);
1377
                }
1378
        // Write V data
1379
        for(y=0; y<height/2; y++)
1380
                  if(fwrite(pFrame->data[2]+y*pFrame->linesize[2], 1, width/2, pFile) != width/2)
1381
                  {
1382
                        printf("errno = %d\n", errno);
1383
                        exit(1);
1384
                }
1385
  
1386
        // Close file
1387
        fclose(pFile);
1388
}
1389
1390
void SaveEncodedFrame(Frame* frame, uint8_t *video_outbuf)
1391
{
1392
        static FILE* pFile = NULL;
1393
        
1394
        pFile=fopen("yuv_data/streamer_out.mpeg4", "ab");
1395
        fwrite(frame, sizeof(Frame), 1, pFile);
1396
        fwrite(video_outbuf, frame->size, 1, pFile);
1397
        fclose(pFile);
1398
}