ffmepg mux h264 aac

static int decode_interrupt_cb(void *ctx) {

    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)ctx;
    int src = pThreadArgs->src;

	return g_bSaveStream[src] == HI_TRUE?0:1;
}

static AVStream *add_stream(AVFormatContext *ofmt_ctx, AVCodecParameters *in_codecpar, int pid)
{
	int Ret;
    AVStream * out_stream = avformat_new_stream(ofmt_ctx, NULL);
    if (!out_stream) {
        printf("Failed allocating output stream\n");
		return NULL;
    }

    Ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
    if (Ret < 0) {
        printf("Failed to copy codec parameters\n");
		return NULL;
    }

	out_stream->id = pid;
    out_stream->codecpar->codec_tag = 0;
	return out_stream;
}

//int gtestfd;
//output ts pkt
int ts_out_callback(void *opaque, uint8_t *buf, int buf_size)
{	
    //printf("%s   IN buf_size  %d  --line-- %d\n",__FUNCTION__, buf_size,__LINE__);
    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)opaque;
    int index ;
	index= pThreadArgs->src;

	
	//write(gtestfd, buf, buf_size);
    buf_size = CamTSMuxer_WriteData(index, buf, buf_size);
    //printf("%s  --line-- OUT  %d \n",__FUNCTION__,__LINE__);
	return buf_size;
}

int get_h264_buffer(void *opaque, uint8_t *buf, int buf_size)
{	

    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)opaque;
    int src = pThreadArgs->src;
	int Ret;
    HI_BOOL bGotStream;
    HI_UNF_VENC_STREAM_S stVencStream;
    //printf("%s  --line-- src %d buf_size %d  IN %d \n",__FUNCTION__, src,buf_size,__LINE__);
    /*save video stream*/
    while (g_bSaveStream[src] == HI_TRUE)
    {
		pthread_mutex_lock(&g_VencMutex[src]);
		Ret = HI_UNF_VENC_AcquireStream(hVenc[src],&stVencStream,0);

		if ((HI_SUCCESS == Ret) && (stVencStream.u32SlcLen > 0))
		{
			buf_size = FFMIN(buf_size, stVencStream.u32SlcLen);
			if (stVencStream.u32SlcLen > buf_size)
    			printf("%s  --line-- buf_size %d  u32SlcLen %d  %d \n",__FUNCTION__, buf_size,stVencStream.u32SlcLen, __LINE__);
			memcpy(buf, stVencStream.pu8Addr, buf_size);
    		//printf("video pts write index %d\n", g_vpts_w_index[src]);
			//g_video_pts_queue[src][g_vpts_w_index[src]] = stVencStream.u32PtsMs;
			g_video_pts_queue[src][0] = stVencStream.u32PtsMs;
			if (g_vpts_w_index[src]+1 >= MAX_PTS_QUEUE_SIZE)
				g_vpts_w_index[src] = 0;
			else
				g_vpts_w_index[src] ++;

			Ret = HI_UNF_VENC_ReleaseStream(hVenc[src],&stVencStream);
			if (HI_SUCCESS != Ret)
			{
				printf("[%s] HI_UNF_VENC_ReleaseStream failed 0x%x\n", __FUNCTION__, Ret);
				pthread_mutex_unlock(&g_VencMutex[src]);
				return -1;
			}

			vencsize[src] += stVencStream.u32SlcLen;
			pthread_mutex_unlock(&g_VencMutex[src]);

            bGotStream = HI_TRUE;
			return  buf_size;//success
		}
		else if ( HI_ERR_VENC_BUF_EMPTY != Ret)
		{
			printf("HI_UNF_VENC_AcquireStream failed:%#x\n",Ret);
			pthread_mutex_unlock(&g_VencMutex[src]);
			return -1;
		}
		pthread_mutex_unlock(&g_VencMutex[src]);
		usleep(2000);
	}
    //printf("%s  --line-- OUT %d \n",__FUNCTION__, __LINE__);
	return -1;
}

int get_aac_buffer(void *opaque, uint8_t *buf, int buf_size)
{	
    //printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)opaque;
    int src = pThreadArgs->src;
    HI_BOOL bGotStream;
	int Ret;
    //HI_UNF_VENC_STREAM_S stTencStream;
    HI_UNF_ES_BUF_S stAencStream;

    while (g_bSaveStream[src] == HI_TRUE)
    {
       /*save audio stream*/
        if(g_bAudioTranscoding[src] == HI_TRUE)
        {
            Ret = HI_UNF_AENC_AcquireStream(hAenc[src],&stAencStream,0);
            if ((HI_SUCCESS == Ret) && (stAencStream.u32BufLen > 0))
            {
				buf_size = FFMIN(buf_size, stAencStream.u32BufLen);
				memcpy(buf, stAencStream.pu8Buf, buf_size);
    			//printf("audio pts write index %d\n", g_apts_w_index[src]);
				g_audio_pts_queue[src][g_apts_w_index[src]] = stAencStream.u32PtsMs;
				//g_audio_pts_queue[src][0] = stAencStream.u32PtsMs;
				if (g_apts_w_index[src]+1 >= MAX_PTS_QUEUE_SIZE)
					g_apts_w_index[src] = 0;
				else
					g_apts_w_index[src] ++;

                Ret = HI_UNF_AENC_ReleaseStream(hAenc[src],&stAencStream);
                if (HI_SUCCESS != Ret)
                {
                    printf("[%s] HI_UNF_AENC_ReleaseStream failed 0x%x\n", __FUNCTION__, Ret);
					return -1;
                }
                aencsize[src] += stAencStream.u32BufLen;
                bGotStream = HI_TRUE;
				return buf_size;
            }
            else if ( HI_ERR_AENC_OUT_BUF_EMPTY != Ret)
            {
                printf("HI_UNF_AENC_AcquireStream failed:%#x\n",Ret);
				return -1;
            }
        }
		usleep(2000);
	}

	return -1;
}

HI_VOID SaveAudioThread(HI_VOID *args)
{
    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)args;
    //HI_HANDLE XCodeHandle = pThreadArgs->XCodeHandle;
    int src = pThreadArgs->src;
    AVPacket pkt = { 0 }; // data and size must be 0;
    av_init_packet(&pkt);
	int Ret;
	int drop_audio = 100;
    printf("SaveAudioThread enter ...........................for src=(%d)\n",src);
    while (g_bSaveStream[src] == HI_TRUE)
    {
		Ret = av_read_frame(g_ifmt_ctx_a[src], &pkt);
		if (Ret < 0)
		    break;

		pthread_mutex_lock(&g_wirteframelock);

		if (drop_audio > 0)
		{
			pkt.stream_index = 1;
			//printf("audio pts read index %d\n", g_apts_r_index[src]);
			pkt.pts = (g_audio_pts_queue[src][g_apts_r_index[src]]) * 90;
			//pkt.pts = (g_audio_pts_queue[src][0]) * 90;
			pkt.dts =  (GetSysTimeMs() -g_Muxing_time[src])*90 + 20000*90;//pkt.pts;

			if (g_apts_r_index[src]+1 >= MAX_PTS_QUEUE_SIZE) 
				g_apts_r_index[src] = 0;
			else 
				g_apts_r_index[src] ++;
			Ret = av_interleaved_write_frame(g_ofmt_ctx[src], &pkt);
			if (Ret < 0) {
				printf("Error muxing audio packet\n");
			}
		}
		else
			drop_audio--;

		pthread_mutex_unlock(&g_wirteframelock);

		av_packet_unref(&pkt);
	}
}

HI_VOID SaveThread(HI_VOID *args)
{
    THREAD_ARGS_S *pThreadArgs = (THREAD_ARGS_S*)args;
    HI_HANDLE XCodeHandle;
    int src;

    HI_S32                Ret;

    XCodeHandle = pThreadArgs->XCodeHandle;
    src = pThreadArgs->src;
	//gtestfd = open("/tmp/test2.ts", O_CREAT|O_RDWR|O_TRUNC, 0666);


	AVOutputFormat *fmt = NULL;
    AVFormatContext *ofmt_ctx;
	AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL;

	g_Muxing_time[src]  = GetSysTimeMs();

	g_vpts_r_index[src] = 0;
	g_vpts_w_index[src] = 0;
	g_apts_r_index[src] = 0;
	g_apts_w_index[src] = 0;

    AVPacket pkt = { 0 }; // data and size must be 0;
    av_init_packet(&pkt);
    printf("SaveThread enter ...........................for src=(%d)\n",src);
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);

    /* allocate the input video context */
	unsigned char* inbuffer_v = NULL;
	inbuffer_v = (unsigned char*)av_malloc(1024*1024*2);
	AVIOContext *avio_in_v = avio_alloc_context(inbuffer_v, 1024*1024*2, 0, args, get_h264_buffer, NULL,NULL); 
	avio_in_v->max_packet_size = 128*1024;

	ifmt_ctx_v = avformat_alloc_context();
    ifmt_ctx_v->interrupt_callback.callback = decode_interrupt_cb;
    ifmt_ctx_v->interrupt_callback.opaque = args;
	ifmt_ctx_v->probesize = 1024*512;
	ifmt_ctx_v->max_analyze_duration = 2 * AV_TIME_BASE;
	ifmt_ctx_v->pb = avio_in_v;

	AVInputFormat *file_iformat_v = av_find_input_format("h264");
	if ((Ret = avformat_open_input(&ifmt_ctx_v, "", file_iformat_v, 0)) < 0) {
		printf( "Could not open input file.\n");
        return ;
	}

	if ((Ret = avformat_find_stream_info(ifmt_ctx_v, 0)) < 0) {
		printf( "Failed to retrieve input stream information\n");
        return ;
	}

    av_dump_format(ifmt_ctx_v, 0, "video", 0);

    /* allocate the input audio context */
	unsigned char* inbuffer_a = NULL;
	inbuffer_a = (unsigned char*)av_malloc(1024*128);
	AVIOContext *avio_in_a = avio_alloc_context(inbuffer_a, 1024*128, 0, args, get_aac_buffer, NULL,NULL); 
	avio_in_a->max_packet_size = 64*1024;

	ifmt_ctx_a = avformat_alloc_context();
    ifmt_ctx_a->interrupt_callback.callback = decode_interrupt_cb;
    ifmt_ctx_a->interrupt_callback.opaque = args;
	ifmt_ctx_a->probesize = 1024*32;
	ifmt_ctx_a->max_analyze_duration = 2 * AV_TIME_BASE;
	ifmt_ctx_a->pb = avio_in_a;

 
	AVInputFormat *file_iformat_a = av_find_input_format("aac");
	if ((Ret = avformat_open_input(&ifmt_ctx_a, "", file_iformat_a, 0)) < 0) {
		printf( "Could not open input file.\n");
        return ;
	}
	if ((Ret = avformat_find_stream_info(ifmt_ctx_a, 0)) < 0) {
		printf( "Failed to retrieve input stream information\n");
        return ;
	}
    av_dump_format(ifmt_ctx_a, 0, "audio", 0);

	unsigned char* outbuffer = NULL;
	outbuffer = (unsigned char*)av_malloc(1024*64);
	AVIOContext *avio_out = avio_alloc_context(outbuffer, 1024*64, 1,  args, NULL, ts_out_callback,NULL); 
    /* allocate the output media context */

    avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", NULL);
    if (!ofmt_ctx) {
        printf("Could not create output context\n");
        Ret = AVERROR_UNKNOWN;
        return ;
    }
	ofmt_ctx->pb = avio_out;

	ofmt_ctx->interrupt_callback.callback = decode_interrupt_cb;
	ofmt_ctx->interrupt_callback.opaque = args;
	ofmt_ctx->flags =AVFMT_FLAG_CUSTOM_IO;
	ofmt_ctx->flags |= AVFMT_FLAG_FLUSH_PACKETS;
    fmt = ofmt_ctx->oformat;
	fmt->flags |= AVFMT_NOFILE;	
	fmt->flags |= AVFMT_TS_NONSTRICT;

    /* Add the audio and video streams using the default format codecs
     * and initialize the codecs. */

    CTSMUX_DESCR_PRG_STREAM * pStr= NULL; 
    pTsDescr[src]->curPrg = pTsDescr[src]->pPrg[0];

#if 1
    AVStream *in_stream_v = ifmt_ctx_v->streams[0];
    AVCodecParameters *in_codecpar_v = in_stream_v->codecpar;
	pStr = &(pTsDescr[src]->curPrg->stream[0]);
	add_stream(ofmt_ctx, in_codecpar_v, pStr->pid);
#endif

#if 1
    AVStream *in_stream_a = ifmt_ctx_a->streams[0];
    AVCodecParameters *in_codecpar_a = in_stream_a->codecpar;
	pStr = &(pTsDescr[src]->curPrg->stream[1]);
	add_stream(ofmt_ctx, in_codecpar_a, pStr->pid);
#endif

    //av_dump_format(ofmt_ctx, 0, "out_ts", 0);

    AVDictionary *opt = NULL;
	av_dict_set_int(&opt, "mpegts_pmt_start_pid", pTsDescr[src]->curPrg->pmt.pid, 0);
    /* Write the stream header, if any. */
    Ret = avformat_write_header(ofmt_ctx, &opt);
    if (Ret < 0) {
        fprintf(stderr, "Error occurred when opening output file: %s\n",
                av_err2str(Ret));
        return ;
    }
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
	g_ifmt_ctx_a[src] = ifmt_ctx_a;
	g_ofmt_ctx[src] = ofmt_ctx;
	pthread_t audio_Thd;
    pthread_create(&audio_Thd, HI_NULL, (HI_VOID *)SaveAudioThread, args);

#if 1
    while (g_bSaveStream[src] == HI_TRUE)
    {
#if 1
		{
			Ret = av_read_frame(ifmt_ctx_v, &pkt);
			if (Ret < 0)
			    break;
			pthread_mutex_lock(&g_wirteframelock);
			//av_packet_rescale_ts(&pkt, in_stream->time_base, out_stream->time_base);
			//pkt.pos = -1;
    		//printf("video pts read index %d\n", g_vpts_r_index[src]);
			//pkt.pts = (g_video_pts_queue[src][g_vpts_r_index[src]]) * 90;
			pkt.pts = (g_video_pts_queue[src][0]) * 90;
			pkt.dts =  pkt.pts;

			if (g_vpts_r_index[src]+1 >= MAX_PTS_QUEUE_SIZE) 
				g_vpts_r_index[src] = 0;
			else 
				g_vpts_r_index[src] ++;

			
			Ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
			if (Ret < 0) {
				printf("Error muxing video packet\n");
			}
			pthread_mutex_unlock(&g_wirteframelock);
			av_packet_unref(&pkt);
		}
#endif

#if 0
		{
			Ret = av_read_frame(g_ifmt_ctx_a[src], &pkt);
			if (Ret < 0)
				break;

			//pthread_mutex_lock(&g_wirteframelock);
			pkt.stream_index = 1;
			Ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
			if (Ret < 0) {
				printf("Error muxing audio packet\n");
			}
			//pthread_mutex_unlock(&g_wirteframelock);
			av_packet_unref(&pkt);
		}
#endif
		
    }
#endif


	pthread_join(audio_Thd, NULL);

	//close(gtestfd);

    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
	av_write_trailer(ofmt_ctx);
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
        avio_closep(&ofmt_ctx->pb);

    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
	avformat_free_context(ofmt_ctx);
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    av_dict_free(&opt);
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    if (avio_out) {
        av_freep(&avio_out->buffer);
        av_freep(&avio_out);
    }
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    avformat_close_input(&ifmt_ctx_v);
    if (avio_in_v) {
        av_freep(&avio_in_v->buffer);
        av_freep(&avio_in_v);
    }
    printf("%s  --line-- %d \n",__FUNCTION__, __LINE__);
    avformat_close_input(&ifmt_ctx_a);
    if (avio_in_a) {
        av_freep(&avio_in_a->buffer);
        av_freep(&avio_in_a);
    }

    printf("SaveThread exit ...........................for src=(%d) \n",src);

    return;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章