Revision 648357d7 chunker_streamer.c

View differences:

chunker_streamer.c
21 21
//#define DEBUG_CHUNKER
22 22
//#define DEBUG_TIME
23 23

  
24
ChunkerMetadata *cmeta = NULL;
24 25

  
25
/*
26
int alphasortNew(const struct dirent **a, const struct dirent **b) {
27
	int idx1 = atoi((*a)->d_name+5);
28
	int idx2 = atoi((*b)->d_name+5);
29
	return (idx2<idx1);
30
//	return (strcmp((*a)->d_name,(*b)->d_name));
31
}
32
*/
33

  
34
ChunkerMetadata *cmeta=NULL;
35 26

  
36 27
int chunkFilled(ExternalChunk *echunk, ChunkerMetadata *cmeta) {
37 28
	// different strategies to implement
......
113 104

  
114 105
int main(int argc, char *argv[]) {
115 106
	int i=0;
116
	int videoStream, outbuf_size, out_size, seq_current_chunk = 1, audioStream; //HINT MORE BYTES IN SEQ
117
	int len1, data_size;
107

  
108
	//output variables
109
	int seq_current_chunk = 1; //chunk numbering starts from 1; HINT do i need more bytes?
110
	uint8_t *video_outbuf = NULL;
111
	int video_outbuf_size, video_frame_size;
112
	uint8_t *audio_outbuf = NULL;
113
	int audio_outbuf_size, audio_frame_size;
114
	int audio_data_size;
115

  
116
	//numeric identifiers of input streams
117
	int videoStream = -1;
118
	int audioStream = -1;
119

  
120
	int len1;
118 121
	int frameFinished;
119
	int numBytes, outbuf_audio_size, audio_size;
120
	int sizeFrame = 0;
121
	int sizeChunk = 0;
122
	int dir_entries;
122
	//frame sequential counters
123
	int contFrameAudio=0, contFrameVideo=0;
124
	int numBytes;
125

  
126
	//command line parameters
123 127
	int audio_bitrate;
124 128
	int video_bitrate;
125
	int contFrameAudio=0, contFrameVideo=0;
126
	int live_source=0;
129
	int live_source = 0;
127 130
	
128
	uint8_t *buffer,*outbuf,*outbuf_audio;
129
	uint8_t *outbuf_audi_audio,*tempdata;
130
	//uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
131
	uint16_t *audio_buf = NULL;
131
	//a raw buffer for decoded uncompressed audio samples
132
	int16_t *samples = NULL;
133
	//a raw uncompressed video picture
134
	AVFrame *pFrame = NULL;
132 135

  
133
	unsigned int audio_buf_size = 0;
134
	long double newtimestamp;
135
	
136 136
	AVFormatContext *pFormatCtx;
137 137
	AVCodecContext  *pCodecCtx,*pCodecCtxEnc,*aCodecCtxEnc,*aCodecCtx;
138 138
	AVCodec         *pCodec,*pCodecEnc,*aCodec,*aCodecEnc;
139
	AVFrame         *pFrame; 
140
	AVFrame         *pFrameRGB;
141 139
	AVPacket         packet;
142
	int64_t last_pkt_dts=0, delta_video=0, delta_audio=0, last_pkt_dts_audio=0, target_pts=0;
143 140

  
144
	Frame *frame=NULL;
145

  
146
	ExternalChunk *chunk=NULL;
147
	ExternalChunk *chunkaudio=NULL;
141
	//Napa-Wine specific Frame and Chunk structures for transport
142
	Frame *frame = NULL;
143
	ExternalChunk *chunk = NULL;
144
	ExternalChunk *chunkaudio = NULL;
148 145
	
149
	char buf[1024], outfile[1024], basedelfile[1024], delfile[1024];
146
	//char buf[1024], outfile[1024];
147

  
148
	//stuff needed to compute the right timestamps
150 149
	short int FirstTimeAudio=1, FirstTimeVideo=1;
151 150
	long long newTime;
152

  
153 151
	double ptsvideo1=0.0;
154 152
	double ptsaudio1=0.0;
155
	
156
//	struct dirent **namelist;
157
	
153
	int64_t last_pkt_dts=0, delta_video=0, delta_audio=0, last_pkt_dts_audio=0, target_pts=0;
154

  
155

  
156
	//scan the command line
158 157
	if(argc < 4) {
159 158
		fprintf(stderr, "execute ./chunker_streamer moviefile audiobitrate videobitrate <live source flag (0 or 1)>\n");
160 159
		return -1;
......
168 167
	if(live_source)
169 168
		fprintf(stderr, "INIT: Using LIVE SOURCE TimeStamps\n");
170 169

  
171
	audio_buf = (uint16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
172
	outbuf_audio_size = 10000;
173
	outbuf_audio = malloc(outbuf_audio_size);
174

  
175 170
	// Register all formats and codecs
176 171
	av_register_all();
177 172

  
178
	// Open video file
173
	// Open input file
179 174
	if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL) != 0) {
180 175
		fprintf(stdout, "INIT: Couldn't open video file. Exiting.\n");
181 176
		exit(-1);
......
190 185
	// Dump information about file onto standard error
191 186
	dump_format(pFormatCtx, 0, argv[1], 0);
192 187

  
193
	// Find the first video stream
194
	videoStream=-1;
195
	audioStream=-1;
196
	
188
	// Find the video and audio stream numbers
197 189
	for(i=0; i<pFormatCtx->nb_streams; i++) {
198 190
		if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream<0) {
199 191
			videoStream=i;
......
212 204
		exit(-1);
213 205
	}
214 206

  
215
	// Get a pointer to the codec context for the video stream
207
	// Get a pointer to the codec context for the input video stream
216 208
	pCodecCtx=pFormatCtx->streams[videoStream]->codec;
217 209
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
210
	//extract W and H
211
	fprintf(stderr, "INIT: Width:%d Height:%d\n", pCodecCtx->width, pCodecCtx->height);
218 212

  
219
	fprintf(stderr, "INIT: Width:%d Height:%d\n",pCodecCtx->width,pCodecCtx->height);
220

  
221
	if(audioStream!=-1) {
213
	// Get a pointer to the codec context for the input audio stream
214
	if(audioStream != -1) {
222 215
		aCodecCtx=pFormatCtx->streams[audioStream]->codec;
223 216
		fprintf(stderr, "INIT: AUDIO Codecid: %d channels %d samplerate %d\n", aCodecCtx->codec_id, aCodecCtx->channels, aCodecCtx->sample_rate);
224 217
	}
225 218

  
219
	//setup video output encoder
226 220
	pCodecCtxEnc=avcodec_alloc_context();
227 221
#ifdef H264_VIDEO_ENCODER
228 222
	pCodecCtxEnc->me_range=16;
......
255 249
#endif
256 250
	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);
257 251

  
252
	// Find the decoder for the video stream
253
#ifdef H264_VIDEO_ENCODER
254
	fprintf(stderr, "INIT: Setting VIDEO codecID to H264: %d %d\n",pCodecCtx->codec_id, CODEC_ID_H264);
255
	pCodecEnc = avcodec_find_encoder(CODEC_ID_H264);//pCodecCtx->codec_id);
256
#else
257
	fprintf(stderr, "INIT: Setting VIDEO codecID to mpeg4: %d %d\n",pCodecCtx->codec_id, CODEC_ID_MPEG4);
258
	pCodecEnc = avcodec_find_encoder(CODEC_ID_MPEG4);
259
#endif
260
	if(pCodec==NULL) {
261
		fprintf(stderr, "INIT: Unsupported IN VIDEO pcodec!\n");
262
		return -1; // Codec not found
263
	}
264
	if(pCodecEnc==NULL) {
265
		fprintf(stderr, "INIT: Unsupported OUT VIDEO pcodecenc!\n");
266
		return -1; // Codec not found
267
	}
268
	if(avcodec_open(pCodecCtx, pCodec)<0) {
269
		fprintf(stderr, "INIT: could not open IN VIDEO codec\n");
270
		return -1; // Could not open codec
271
	}
272
	if(avcodec_open(pCodecCtxEnc, pCodecEnc)<0) {
273
		fprintf(stderr, "INIT: could not open OUT VIDEO codecEnc\n");
274
		return -1; // Could not open codec
275
	}
258 276

  
277

  
278
	//setup audio output encoder
259 279
	aCodecCtxEnc = avcodec_alloc_context();
260 280
	aCodecCtxEnc->bit_rate = audio_bitrate; //256000
261 281
	aCodecCtxEnc->sample_fmt = SAMPLE_FMT_S16;
262 282
	aCodecCtxEnc->sample_rate = aCodecCtx->sample_rate;
263 283
	aCodecCtxEnc->channels = aCodecCtx->channels;
264
        //fprintf(stderr, "InitAUDIOFRAMESIZE:%d %d\n",aCodecCtxEnc->frame_size,av_rescale(44100,1,25));
265 284
	fprintf(stderr, "INIT: AUDIO bitrate OUT:%d sample_rate:%d channels:%d\n", aCodecCtxEnc->bit_rate, aCodecCtxEnc->sample_rate, aCodecCtxEnc->channels);
266 285

  
267
	// Find the decoder for the video stream
268
	
286
	// Find the decoder for the audio stream
269 287
	if(audioStream!=-1) {
270 288
		aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
271 289
#ifdef MP3_AUDIO_ENCODER
......
290 308
			fprintf(stderr, "INIT: could not open OUT AUDIO codec\n");
291 309
			return -1; // Could not open codec
292 310
		}
293

  
294
	}
295
#ifdef H264_VIDEO_ENCODER
296
	fprintf(stderr, "INIT: Setting VIDEO codecID to H264: %d %d\n",pCodecCtx->codec_id, CODEC_ID_H264);
297
	pCodecEnc = avcodec_find_encoder(CODEC_ID_H264);//pCodecCtx->codec_id);
298
#else
299
	fprintf(stderr, "INIT: Setting VIDEO codecID to mpeg4: %d %d\n",pCodecCtx->codec_id, CODEC_ID_MPEG4);
300
	pCodecEnc = avcodec_find_encoder(CODEC_ID_MPEG4);
301
#endif
302
	if(pCodec==NULL) {
303
		fprintf(stderr, "INIT: Unsupported IN VIDEO pcodec!\n");
304
		return -1; // Codec not found
305
	}
306
	if(pCodecEnc==NULL) {
307
		fprintf(stderr, "INIT: Unsupported OUT VIDEO pcodecenc!\n");
308
		return -1; // Codec not found
309 311
	}
310
	if(avcodec_open(pCodecCtx, pCodec)<0) {
311
		fprintf(stderr, "INIT: could not open IN VIDEO codec\n");
312
		return -1; // Could not open codec
312

  
313
	// Allocate audio in and out buffers
314
	samples = (int16_t *)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
315
	if(samples == NULL) {
316
		fprintf(stderr, "INIT: Memory error alloc audio samples!!!\n");
317
		return -1;
313 318
	}
314
	if(avcodec_open(pCodecCtxEnc, pCodecEnc)<0) {
315
		fprintf(stderr, "INIT: could not open OUT VIDEO codecEnc\n");
316
		return -1; // Could not open codec
319
	audio_outbuf_size = STREAMER_MAX_AUDIO_BUFFER_SIZE;
320
	audio_outbuf = av_malloc(audio_outbuf_size);
321
	if(audio_outbuf == NULL) {
322
		fprintf(stderr, "INIT: Memory error alloc audio_outbuf!!!\n");
323
		return -1;
317 324
	}
318 325

  
319
	// Allocate video frame
326
	// Allocate video in frame and out buffer
320 327
	pFrame=avcodec_alloc_frame();
321 328
	if(pFrame==NULL) {
322 329
		fprintf(stderr, "INIT: Memory error alloc video frame!!!\n");
323 330
		return -1;
324 331
	}
325
  
326
	i=0;
327
	outbuf_size = 100000;
328
	outbuf = malloc(outbuf_size);
329
	if(!outbuf) {
330
		fprintf(stderr, "INIT: Memory error alloc outbuf!!!\n");
332
	video_outbuf_size = STREAMER_MAX_VIDEO_BUFFER_SIZE;
333
	video_outbuf = av_malloc(video_outbuf_size);
334
	if(!video_outbuf) {
335
		fprintf(stderr, "INIT: Memory error alloc video_outbuf!!!\n");
331 336
		return -1;
332 337
	}
338

  
339
	//allocate Napa-Wine transport
333 340
	frame = (Frame *)malloc(sizeof(Frame));
334 341
	if(!frame) {
335 342
		fprintf(stderr, "INIT: Memory error alloc Frame!!!\n");
336 343
		return -1;
337 344
	}
338
	sizeFrame = 3*sizeof(int32_t)+sizeof(struct timeval);
339 345
	chunk = (ExternalChunk *)malloc(sizeof(ExternalChunk));
340 346
	if(!chunk) {
341 347
		fprintf(stderr, "INIT: Memory error alloc chunk!!!\n");
342 348
		return -1;
343 349
	}
344
	sizeChunk = 6*sizeof(int32_t)+2*sizeof(struct timeval)+sizeof(double);
345
    chunk->data=NULL;
350

  
351
	//init an empty first video chunk
352
	chunk->data=NULL;
346 353
	initChunk(chunk, &seq_current_chunk);
347 354
#ifdef DEBUG_CHUNKER
348 355
	fprintf(stderr, "INIT: chunk video %d\n", chunk->seq);
349 356
#endif
357
	//init empty first audio chunk
350 358
	chunkaudio = (ExternalChunk *)malloc(sizeof(ExternalChunk));
351 359
	if(!chunkaudio) {
352 360
		fprintf(stderr, "INIT: Memory error alloc chunkaudio!!!\n");
353 361
		return -1;
354 362
	}
355
    chunkaudio->data=NULL;
363
  chunkaudio->data=NULL;
356 364
	initChunk(chunkaudio, &seq_current_chunk);
357 365
#ifdef DEBUG_CHUNKER
358 366
	fprintf(stderr, "INIT: chunk audio %d\n", chunkaudio->seq);
359 367
#endif
360
	//av_init_packet(&packet);
361 368

  
362 369
	/* initialize the HTTP chunk pusher */
363 370
	initChunkPusher(); //TRIPLO
364 371

  
372
//	i=0;
365 373

  
374
	//main loop to read from the input file
366 375
	while(av_read_frame(pFormatCtx, &packet)>=0) {
367 376
		// Is this a packet from the video stream?
368 377
		if(packet.stream_index==videoStream) {
369
			// Decode video frame
378
			//decode the video packet into a raw pFrame
370 379
			if(avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet)>0) {
371 380
#ifdef DEBUG_VIDEO_FRAMES
372 381
				fprintf(stderr, "-------VIDEO FRAME type %d\n", pFrame->pict_type);
......
387 396
					else {
388 397
						if(packet.dts!=AV_NOPTS_VALUE) {
389 398
							delta_video = packet.dts-last_pkt_dts;
390
/*
391
							DeltaTimeVideo=((double)packet.dts-(double)last_pkt_dts)*1000.0/((double)delta_video*(double)av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate));
392
							if(DeltaTimeVideo<0) DeltaTimeVideo=10;
393
							if(DeltaTimeVideo>80) DeltaTimeVideo=80;
394
*/
395 399
							last_pkt_dts = packet.dts;
396 400
						}
397 401
						else if(delta_video==0)
......
401 405
#ifdef DEBUG_VIDEO_FRAMES
402 406
					fprintf(stderr, "VIDEO: deltavideo : %d\n", (int)delta_video);
403 407
#endif
404
					out_size = avcodec_encode_video(pCodecCtxEnc, outbuf, outbuf_size, pFrame);
408
					video_frame_size = avcodec_encode_video(pCodecCtxEnc, video_outbuf, video_outbuf_size, pFrame);
405 409
#ifdef DEBUG_VIDEO_FRAMES
406 410
					fprintf(stderr, "VIDEO: original codec frame number %d\n", pCodecCtx->frame_number);
407 411
					fprintf(stderr, "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);
......
425 429
#endif
426 430
						}
427 431
						if(frame->number>0) {
428
							//if(ptsaudio1>0)
429
								//use audio-based timestamps when available (both for video and audio frames)
430
								//newTime = (((double)target_pts-ptsaudio1)*1000.0*((double)av_q2d(pFormatCtx->streams[audioStream]->time_base)));//*(double)delta_audio;
431
							//else
432
								newTime = ((double)target_pts-ptsvideo1)*1000.0/((double)delta_video*(double)av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate));
432
							newTime = ((double)target_pts-ptsvideo1)*1000.0/((double)delta_video*(double)av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate));
433 433
						}
434 434
					}
435 435
					else //live source
......
449 449
						if(frame->number>0) {
450 450
							newTime = ((double)target_pts-ptsvideo1)*1000.0/((double)delta_video*(double)av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate));
451 451
						}
452
						//this was for on-the-fly timestamping
453
						//newTime=Now-StartTime;
454 452
					}
455 453
#ifdef DEBUG_VIDEO_FRAMES
456 454
					fprintf(stderr, "VIDEO: NEWTIMESTAMP %ld\n", newTime);
......
464 462
	
465 463
					frame->timestamp.tv_sec = (long long)newTime/1000;
466 464
					frame->timestamp.tv_usec = newTime%1000;
467
	
468
					frame->size = out_size;
465
					frame->size = video_frame_size;
469 466
					frame->type = pFrame->pict_type;
470 467
#ifdef DEBUG_VIDEO_FRAMES
471 468
					fprintf(stderr, "VIDEO: encapsulated frame num:%d size:%d type:%d\n", frame->number, frame->size, frame->type);
472 469
					fprintf(stderr, "VIDEO: timestamped sec %d usec:%d\n", frame->timestamp.tv_sec, frame->timestamp.tv_usec);
473
					//fprintf(stderr, "out_size:%d outbuf_size:%d packet.size:%d\n",out_size,outbuf_size,packet.size);
474
#endif
475
					// Save the frame to disk
476
					//++i;
477
					//SaveFrame(pFrame, pCodecCtx->width, pCodecCtx->height, i);
478
					//HINT on malloc
479
					chunk->data = (uint8_t *)realloc(chunk->data, sizeof(uint8_t)*(chunk->payload_len+out_size+sizeFrame));
480
					if(!chunk->data)  {
481
						fprintf(stderr, "Memory error in chunk!!!\n");
482
						return -1;
483
					}
484
					chunk->frames_num++; // number of frames in the current chunk
485
					//lets increase the numbering of the frames
486
					contFrameVideo++;
487
#ifdef DEBUG_VIDEO_FRAMES
488
					//fprintf(stderr, "rialloco data di dim:%d con nuova dim:%d\n",chunk->payload_len,out_size);
489 470
#endif
471
					contFrameVideo++; //lets increase the numbering of the frames
490 472

  
491
					tempdata = chunk->data+chunk->payload_len;
492
					*((int32_t *)tempdata) = frame->number;
493
					tempdata+=sizeof(int32_t);
494
					*((struct timeval *)tempdata) = frame->timestamp;
495
					tempdata+=sizeof(struct timeval);
496
					*((int32_t *)tempdata) = frame->size;
497
					tempdata+=sizeof(int32_t);
498
					*((int32_t *)tempdata) = frame->type;
499
					tempdata+=sizeof(int32_t);
500
					
501
					memcpy(chunk->data+chunk->payload_len+sizeFrame,outbuf,out_size); // insert new data
502
					chunk->payload_len += out_size + sizeFrame; // update payload length
503
					//fprintf(stderr, "outsize:%d payload_len:%d\n",out_size,chunk->payload_len);
504
					chunk->len = sizeChunk+chunk->payload_len ; // update overall length
505
					
506
					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) {
507
						chunk->start_time.tv_sec = frame->timestamp.tv_sec;
508
						chunk->start_time.tv_usec = frame->timestamp.tv_usec;
473
					if(update_chunk(chunk, frame, video_outbuf) == -1) {
474
						fprintf(stderr, "VIDEO: unable to update chunk %d. Exiting.\n", chunk->seq);
475
						exit(-1);
509 476
					}
510
					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) {
511
						chunk->end_time.tv_sec = frame->timestamp.tv_sec;
512
						chunk->end_time.tv_usec = frame->timestamp.tv_usec;
513
					}
514
	
477

  
515 478
					if(chunkFilled(chunk, cmeta)) { // is chunk filled using current strategy?
516 479
						//SAVE ON FILE
517 480
						//saveChunkOnFile(chunk);
......
527 490
			}
528 491
		}
529 492
		else if(packet.stream_index==audioStream) {
530
			data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
531
			if(avcodec_decode_audio3(aCodecCtx, audio_buf, &data_size, &packet)>0) {
493
			audio_data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
494
			//decode the audio packet into a raw audio source buffer
495
			if(avcodec_decode_audio3(aCodecCtx, samples, &audio_data_size, &packet)>0) {
532 496
#ifdef DEBUG_AUDIO_FRAMES
533 497
				fprintf(stderr, "\n-------AUDIO FRAME\n");
534 498
				fprintf(stderr, "AUDIO: newTimeaudioSTART : %lf\n", (double)(packet.pts)*av_q2d(pFormatCtx->streams[audioStream]->time_base));
535 499
#endif
536
				if(data_size>0) {
500
				if(audio_data_size>0) {
537 501
#ifdef DEBUG_AUDIO_FRAMES
538
					fprintf(stderr, "AUDIO: datasizeaudio:%d\n", data_size);
502
					fprintf(stderr, "AUDIO: datasizeaudio:%d\n", audio_data_size);
539 503
#endif
540 504
					/* if a frame has been decoded, output it */
541
					//fwrite(audio_buf, 1, data_size, outfileaudio);
505
					//fwrite(samples, 1, audio_data_size, outfileaudio);
542 506
				}
543 507
				else
544 508
					continue;
545 509
	
546
				audio_size = avcodec_encode_audio(aCodecCtxEnc,outbuf_audio,data_size,audio_buf);
510
				audio_frame_size = avcodec_encode_audio(aCodecCtxEnc, audio_outbuf, audio_data_size, samples);
547 511
				frame->number = contFrameAudio;
548 512

  
549 513
				if(frame->number==0) {
......
555 519
				else {
556 520
					if(packet.dts!=AV_NOPTS_VALUE) {
557 521
						delta_audio = packet.dts-last_pkt_dts_audio;
558
/*
559
						DeltaTimeAudio=(((double)packet.dts-last_pkt_dts_audio)*1000.0*((double)av_q2d(pFormatCtx->streams[audioStream]->time_base)));
560
						if(DeltaTimeAudio<0) DeltaTimeAudio=10;
561
						if(DeltaTimeAudio>1500) DeltaTimeAudio=1500;
562
*/
563 522
						last_pkt_dts_audio = packet.dts;
564 523
					}
565 524
					else if(delta_audio==0)
......
612 571
					}
613 572

  
614 573
					if(frame->number>0) {
615
							//if(ptsaudio1>0)
616
								//use audio-based timestamps when available (both for video and audio frames)
617 574
								newTime = (((double)target_pts-ptsaudio1)*1000.0*((double)av_q2d(pFormatCtx->streams[audioStream]->time_base)));//*(double)delta_audio;
618
							//else
619
							//	newTime = ((double)target_pts-ptsvideo1)*1000.0/((double)delta_video*(double)av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate));
620 575
					}
621
					//this was for on-the-fly timestamping
622
					//newTime=Now-StartTime;
623 576
				}
624 577
#ifdef DEBUG_AUDIO_FRAMES
625 578
				fprintf(stderr, "AUDIO: NEWTIMESTAMP %d\n", newTime);
......
633 586

  
634 587
				frame->timestamp.tv_sec = (unsigned int)newTime/1000;
635 588
				frame->timestamp.tv_usec = newTime%1000;
589
				frame->size = audio_frame_size;
590
				frame->type = 5; // 5 is audio type
636 591
#ifdef DEBUG_AUDIO_FRAMES
637 592
				fprintf(stderr, "AUDIO: pts %d duration %d timebase %d %d dts %d\n", (int)packet.pts, (int)packet.duration, pFormatCtx->streams[audioStream]->time_base.num, pFormatCtx->streams[audioStream]->time_base.den, (int)packet.dts);
638 593
				fprintf(stderr, "AUDIO: timestamp sec:%d usec:%d\n", frame->timestamp.tv_sec, frame->timestamp.tv_usec);
639 594
				fprintf(stderr, "AUDIO: deltaaudio %lld\n", delta_audio);	
640 595
#endif
641

  
642
				frame->size = audio_size;
643
				frame->type = 5; // 5 is audio type
644

  
645
				chunkaudio->data = (uint8_t *)realloc(chunkaudio->data,sizeof(uint8_t)*(chunkaudio->payload_len+audio_size+sizeFrame));
646
				if(!chunkaudio->data) {
647
					fprintf(stderr, "Memory error AUDIO chunk!!!\n");
648
					return -1;
649
				}
650
				chunkaudio->frames_num++; // number of frames in the current chunk
651 596
				contFrameAudio++;
652
				tempdata = chunkaudio->data+chunkaudio->payload_len;
653
				*((int32_t *)tempdata) = frame->number;
654
				tempdata+=sizeof(int32_t);
655
				*((struct timeval *)tempdata) = frame->timestamp;
656
				tempdata+=sizeof(struct timeval);
657
				*((int32_t *)tempdata) = frame->size;
658
				tempdata+=sizeof(int32_t);
659
				*((int32_t *)tempdata) = frame->type;
660
				tempdata+=sizeof(int32_t);
661
					
662
				memcpy(chunkaudio->data+chunkaudio->payload_len+sizeFrame,outbuf_audio,audio_size);
663
				chunkaudio->payload_len += audio_size + sizeFrame; // update payload length
664
					//fprintf(stderr, "outsize:%d payload_len:%d\n",out_size,chunk->payload_len);
665
				chunkaudio->len = sizeChunk+chunkaudio->payload_len ; // update overall length
666
				
667
				if(((int)frame->timestamp.tv_sec < (int)chunkaudio->start_time.tv_sec) || ((int)frame->timestamp.tv_sec==(int)chunkaudio->start_time.tv_sec && (int)frame->timestamp.tv_usec < (int)chunkaudio->start_time.tv_usec) || (int)chunkaudio->start_time.tv_sec==-1) {
668
					chunkaudio->start_time.tv_sec = frame->timestamp.tv_sec;
669
					chunkaudio->start_time.tv_usec = frame->timestamp.tv_usec;
670
				}
671
				if(((int)frame->timestamp.tv_sec > (int)chunkaudio->end_time.tv_sec) || ((int)frame->timestamp.tv_sec==(int)chunkaudio->end_time.tv_sec && (int)frame->timestamp.tv_usec > (int)chunkaudio->end_time.tv_usec) || (int)chunkaudio->end_time.tv_sec==-1) {
672
					chunkaudio->end_time.tv_sec = frame->timestamp.tv_sec;
673
					chunkaudio->end_time.tv_usec = frame->timestamp.tv_usec;
674
				}
675 597

  
598
				if(update_chunk(chunkaudio, frame, audio_outbuf) == -1) {
599
					fprintf(stderr, "AUDIO: unable to update chunk %d. Exiting.\n", chunkaudio->seq);
600
					exit(-1);
601
				}
676 602
				//set priority
677 603
				chunkaudio->priority = 1;
678 604

  
......
715 641
	free(chunk);
716 642
	free(chunkaudio);
717 643
	free(frame);
718
	free(outbuf);
719
	free(outbuf_audio);
644
	av_free(video_outbuf);
645
	av_free(audio_outbuf);
720 646
	free(cmeta);
721 647

  
722 648
	// Free the YUV frame
723 649
	av_free(pFrame);
724
	av_free(audio_buf);
650
	av_free(samples);
725 651
  
726 652
	// Close the codec
727 653
	avcodec_close(pCodecCtx);
......
736 662
	av_close_input_file(pFormatCtx);
737 663
	return 0;
738 664
}
665

  
666

  
667
int update_chunk(ExternalChunk *chunk, Frame *frame, uint8_t *outbuf) {
668
	static int sizeFrameHeader = 3*sizeof(int32_t)+sizeof(struct timeval);
669
	static int sizeChunkHeader = 6*sizeof(int32_t)+2*sizeof(struct timeval)+sizeof(double);
670

  
671
	//moving temp pointer to encode Frame on the wire
672
	uint8_t *tempdata = NULL;
673

  
674
	//HINT on malloc
675
	chunk->data = (uint8_t *)realloc(chunk->data, sizeof(uint8_t)*(chunk->payload_len + frame->size + sizeFrameHeader));
676
	if(!chunk->data)  {
677
		fprintf(stderr, "Memory error in chunk!!!\n");
678
		return -1;
679
	}
680
	chunk->frames_num++; // number of frames in the current chunk
681

  
682
	//package the Frame header
683
	tempdata = chunk->data+chunk->payload_len;
684
	*((int32_t *)tempdata) = frame->number;
685
	tempdata+=sizeof(int32_t);
686
	*((struct timeval *)tempdata) = frame->timestamp;
687
	tempdata+=sizeof(struct timeval);
688
	*((int32_t *)tempdata) = frame->size;
689
	tempdata+=sizeof(int32_t);
690
	*((int32_t *)tempdata) = frame->type;
691
	tempdata+=sizeof(int32_t);
692

  
693
	 //insert the new frame data
694
	memcpy(chunk->data + chunk->payload_len + sizeFrameHeader, outbuf, frame->size);
695
	chunk->payload_len += frame->size + sizeFrameHeader; // update payload length
696
	chunk->len = sizeChunkHeader + chunk->payload_len; // update overall length
697

  
698
	//update timestamps
699
	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) {
700
						chunk->start_time.tv_sec = frame->timestamp.tv_sec;
701
						chunk->start_time.tv_usec = frame->timestamp.tv_usec;
702
	}
703
	
704
	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) {
705
						chunk->end_time.tv_sec = frame->timestamp.tv_sec;
706
						chunk->end_time.tv_usec = frame->timestamp.tv_usec;
707
	}
708
	return 0;
709
}
710

  

Also available in: Unified diff