Revision 7bf61907 chunker_streamer/chunker_streamer.c

View differences:

chunker_streamer/chunker_streamer.c
29 29
struct outstream outstream[1+QUALITYLEVELS_MAX+1];
30 30
int qualitylevels = 3;
31 31
int indexchannel = 1;
32
int passthrough = 1;
32 33

  
33 34
#define DEBUG
34 35
#define DEBUG_AUDIO_FRAMES  false
......
150 151
    "\t[--avfilter]:set input filter (default: yadif\n"
151 152
    "\t[--no-indexchannel]: turn off generation of index channel\n"
152 153
    "\t[--qualitylevels]:set number of quality levels\n"
154
    "\t[--passthrough 0/1]: turn off/on generation of passthrough channel\n"
153 155
    "\n"
154 156
    "Codec options:\n"
155 157
    "\t[-g GOP]: gop size\n"
......
567 569
		{"avfilter", required_argument, 0, 0},
568 570
		{"indexchannel", no_argument, &indexchannel, 1},
569 571
		{"no-indexchannel", no_argument, &indexchannel, 0},
572
		{"passthrough", required_argument, 0, 0},
570 573
		{"qualitylevels", required_argument, 0, 'Q'},
571 574
		{0, 0, 0, 0}
572 575
	};
......
580 583
				if( strcmp( "audio_stream", long_options[option_index].name ) == 0 ) { audioStream = atoi(optarg); }
581 584
				if( strcmp( "video_stream", long_options[option_index].name ) == 0 ) { videoStream = atoi(optarg); }
582 585
				if( strcmp( "avfilter", long_options[option_index].name ) == 0 ) { avfilter = strdup(optarg); }
586
				if( strcmp( "passthrough", long_options[option_index].name ) == 0 ) { passthrough = atoi(optarg); }
583 587
				break;
584 588
			case 'i':
585 589
				sprintf(av_input, "%s", optarg);
......
670 674
		return -2;
671 675
	}
672 676

  
673
	for (i=0; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
677
	for (i=0; i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
674 678
		outstream[i].output = initTCPPush(peer_ip, peer_port+i);
675 679
		if (!outstream[i].output) {
676 680
			fprintf(stderr, "Error initializing output module, exiting\n");
......
755 759
	dest_height = (dest_height > 0) ? dest_height : pCodecCtx->height;
756 760

  
757 761
	//initialize outstream structures
758
	for (i=0; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
762
	for (i=0; i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
759 763
		outstream[i].chunk = (ExternalChunk *)malloc(sizeof(ExternalChunk));
760 764
		if(!outstream[i].chunk) {
761 765
			fprintf(stderr, "INIT: Memory error alloc chunk!!!\n");
......
766 770
		dcprintf(DEBUG_CHUNKER, "INIT: chunk video %d\n", outstream[i].chunk->seq);
767 771
		outstream[i].pCodecCtxEnc = NULL;
768 772
	}
769
	outstream[0].pCodecCtxEnc = NULL;
770
	for (i=1,j=1,k=1; i < 1 + qualitylevels; i++) {
773
	if (passthrough) outstream[0].pCodecCtxEnc = NULL;
774
	for (i=(passthrough?1:0),j=1,k=1; i < (passthrough?1:0) + qualitylevels; i++) {
771 775
		outstream[i].pCodecCtxEnc = openVideoEncoder(video_codec, video_bitrate/j, (dest_width/k/2)*2, (dest_height/k/2)*2, pCodecCtx->time_base, codec_options);	// (w/2)*2, since libx264 requires width,height to be even
772 776
		if (!outstream[i].pCodecCtxEnc) {
773 777
			return -1;
......
776 780
		k*=2;	//reduce dimensions to 1/2
777 781
	}
778 782
	if (indexchannel) {
779
		outstream[qualitylevels + 1].pCodecCtxEnc = openVideoEncoder(video_codec, 50000, 160, 120, pCodecCtx->time_base, codec_options);
780
		if (!outstream[qualitylevels + 1].pCodecCtxEnc) {
783
		outstream[(passthrough?1:0) + qualitylevels].pCodecCtxEnc = openVideoEncoder(video_codec, 50000, 160, 120, pCodecCtx->time_base, codec_options);
784
		if (!outstream[(passthrough?1:0) + qualitylevels].pCodecCtxEnc) {
781 785
			return -1;
782 786
		}
783 787
	}
784 788

  
785
	fprintf(stderr, "INIT: VIDEO timebase OUT:%d %d IN: %d %d\n", outstream[1].pCodecCtxEnc->time_base.num, outstream[1].pCodecCtxEnc->time_base.den, pCodecCtx->time_base.num, pCodecCtx->time_base.den);
789
	//fprintf(stderr, "INIT: VIDEO timebase OUT:%d %d IN: %d %d\n", outstream[1].pCodecCtxEnc->time_base.num, outstream[1].pCodecCtxEnc->time_base.den, pCodecCtx->time_base.num, pCodecCtx->time_base.den);
786 790

  
787 791
	if(pCodec==NULL) {
788 792
		fprintf(stderr, "INIT: Unsupported IN VIDEO pcodec!\n");
......
1029 1033
					}
1030 1034
					dcprintf(DEBUG_VIDEO_FRAMES, "Setting v:%lld\n", newTime_video);
1031 1035

  
1032
					if(true) {	//copy channel
1036
					if(passthrough) {	//copy channel
1033 1037
						video_frame_size = packet.size;
1034 1038
						if (video_frame_size > video_outbuf_size) {
1035 1039
							fprintf(stderr, "VIDEO: error, outbuf too small, SKIPPING\n");;
......
1050 1054
					}
1051 1055

  
1052 1056
					if (pFrame->pkt_pts != AV_NOPTS_VALUE) {
1053
						pFrame->pts = av_rescale_q(pFrame->pkt_pts, pFormatCtx->streams[videoStream]->time_base, outstream[1].pCodecCtxEnc->time_base);
1057
						pFrame->pts = av_rescale_q(pFrame->pkt_pts, pFormatCtx->streams[videoStream]->time_base, outstream[(passthrough?1:0)].pCodecCtxEnc->time_base);
1054 1058
					} else {	//try to figure out the pts //TODO: review this
1055 1059
						if (pFrame->pkt_dts != AV_NOPTS_VALUE) {
1056
							pFrame->pts = av_rescale_q(pFrame->pkt_dts, pFormatCtx->streams[videoStream]->time_base, outstream[1].pCodecCtxEnc->time_base);
1060
							pFrame->pts = av_rescale_q(pFrame->pkt_dts, pFormatCtx->streams[videoStream]->time_base, outstream[(passthrough?1:0)].pCodecCtxEnc->time_base);
1057 1061
						}
1058 1062
					}
1059 1063

  
1060 1064
					pFrame2 = preprocessFrame(pFrame);
1061 1065
					if (pFrame2) pFrame = pFrame2;
1062 1066

  
1063
					for (i=1; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
1067
					for (i=(passthrough?1:0); i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
1064 1068
						video_frame_size = transcodeFrame(video_outbuf, video_outbuf_size, &target_pts, pFrame, pFormatCtx->streams[videoStream]->time_base, pCodecCtx, outstream[i].pCodecCtxEnc);
1065 1069
						if (video_frame_size <= 0) {
1066 1070
							av_free_packet(&packet);
......
1231 1235
					//SAVE ON FILE
1232 1236
					//saveChunkOnFile(chunkaudio);
1233 1237
					//Send the chunk to an external transport/player
1234
					for (i=0; i < 1 + qualitylevels; i++) {	//do not send audio to the index channel
1238
					for (i=0; i < (passthrough?1:0) + qualitylevels; i++) {	//do not send audio to the index channel
1235 1239
						sendChunk(outstream[i].output, chunkaudio);
1236 1240
					}
1237 1241
					dctprintf(DEBUG_CHUNKER, "AUDIO: just sent chunk audio %d\n", chunkaudio->seq);
......
1284 1288
		fclose(psnrtrace);
1285 1289

  
1286 1290
close:
1287
	for (i=0; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
1291
	for (i=0; i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
1288 1292
		if(outstream[i].chunk->seq != 0 && outstream[i].chunk->frames_num>0) {
1289 1293
			sendChunk(outstream[i].output, outstream[0].chunk);
1290 1294
			dcprintf(DEBUG_CHUNKER, "CHUNKER: SENDING LAST VIDEO CHUNK\n");
1291 1295
			outstream[i].chunk->seq = 0; //signal that we need an increase just in case we will restart
1292 1296
		}
1293 1297
	}
1294
	for (i=0; i < 1 + qualitylevels; i++) {
1298
	for (i=0; i < (passthrough?1:0) + qualitylevels; i++) {
1295 1299
		if(chunkaudio->seq != 0 && chunkaudio->frames_num>0) {
1296 1300
			sendChunk(outstream[i].output, chunkaudio);
1297 1301
			dcprintf(DEBUG_CHUNKER, "CHUNKER: SENDING LAST AUDIO CHUNK\n");
......
1304 1308
	finalizeChunkPusher();
1305 1309
#endif
1306 1310

  
1307
	for (i=0; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
1311
	for (i=0; i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
1308 1312
		free(outstream[i].chunk);
1309 1313
	}
1310 1314
	free(chunkaudio);
......
1319 1323
  
1320 1324
	// Close the codec
1321 1325
	avcodec_close(pCodecCtx);
1322
	for (i=1; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
1326
	for (i=(passthrough?1:0); i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
1323 1327
		avcodec_close(outstream[i].pCodecCtxEnc);
1324 1328
	}
1325 1329

  
......
1374 1378
	}
1375 1379

  
1376 1380
#ifdef TCPIO
1377
	for (i=0; i < 1 + qualitylevels + (indexchannel?1:0); i++) {
1381
	for (i=0; i < (passthrough?1:0) + qualitylevels + (indexchannel?1:0); i++) {
1378 1382
		finalizeTCPChunkPusher(outstream[i].output);
1379 1383
	}
1380 1384
#endif

Also available in: Unified diff