FFmpeg multiplexing H264 and AAC for TS Flow

Source: Internet
Author: User
Tags file url goto

Muxerandroid.c

#include <jni.h> #include <string.h> #include <stdio.h> #include <android/log.h> #include < libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <  libavutil/frame.h> #include <libavutil/pixfmt.h> #define LOG_TAG "Ffmpegsample" #define LOGI (...)  __android_log_print (android_log_info,log_tag,__va_args__) #define LOGE (...) __android_log_print (android_log_error,log_tag,__va_args__)/* fix:h.264 in some container format (FLV, MP4, MKV etc.) NE Ed "H264_mp4toannexb" Bitstream filter (BSF) *add Sps,pps in front of IDR frame *add start code ("0,0,0,1") in front
of Nalu H.264 in some container (mpeg2ts) don ' t need this BSF.  
*//' 1 ': use H.264 bitstream Filter #define USE_H264BSF 0/* FIX:AAC in some container format (FLV, MP4, MKV etc.) need "Aac_adtstoasc" bitstream filter (BSF) *//' 1 ': Use AAC bitstream filter #define USE_AACBSF 0 jniexport jint jnical L JAVA_COM_EXAMPLE_FFMPegmuxer_muxerandroid_muxering (JNIENV * env, Jclass obj) {Avoutputformat *ofmt = NULL; Input Avformatcontext and Output avformatcontext avformatcontext *ifmt_ctx_v = NULL, *ifmt_ctx_a = Null,*ofmt_ctx = NUL
	L
	Avpacket PKT;
	int ret, I;
	int videoindex_v=-1,videoindex_out=-1;
	int audioindex_a=-1,audioindex_out=-1;
	int frame_index=0;

	int64_t cur_pts_v=0,cur_pts_a=0; const char *IN_FILENAME_V = "Cuc_ieschool.ts";//input file URL const char *in_filename_v = "/sdcard/muxer/cuc_ieschool.
	H264 ";
	const char *in_filename_a = "Cuc_ieschool.mp3";
	const char *in_filename_a = "GOWEST.M4A";
	const char *in_filename_a = "/SDCARD/MUXER/GOWEST.AAC";

	const char *in_filename_a = "Huoyuanjia.mp3";
	const char *out_filename = "/sdcard/muxer/test.ts";//output file URL av_register_all (); Input if (ret = Avformat_open_input (&ifmt_ctx_v, in_filename_v, 0, 0)) < 0 {Logi ("Could not open input fil
		E. ");
	Goto end; } if (ret = avformat_find_stream_info (ifmt_ctx_v, 0)) &Lt
		0) {Logi ("Failed to retrieve input stream information");
	Goto end; } if (ret = Avformat_open_input (&ifmt_ctx_a, in_filename_a, 0, 0)) < 0 {Logi ("Could not open input file.")
		;
	Goto end;
		The IF (ret = avformat_find_stream_info (ifmt_ctx_a, 0)) < 0) {Logi ("Failed to retrieve input stream information");
	Goto end;
	} logi ("===========input information==========\n");
	Av_dump_format (ifmt_ctx_v, 0, in_filename_v, 0);
	Av_dump_format (ifmt_ctx_a, 0, in_filename_a, 0);
	Logi ("======================================\n");
	Output avformat_alloc_output_context2 (&ofmt_ctx, NULL, NULL, out_filename);
		if (!ofmt_ctx) {Logi ("could not create output context\n");
		ret = Averror_unknown;
	Goto end;

	} ofmt = ofmt_ctx->oformat; for (i = 0, i < ifmt_ctx_v->nb_streams; i++) {//create output avstream according to input avstream if (ifmt_ctx_ V->streams[i]->codec->codec_type==avmedia_type_video) {Avstream *in_stream = ifmt_ctx_v->stReams[i];
		Avstream *out_stream = Avformat_new_stream (Ofmt_ctx, In_stream->codec->codec);
		Videoindex_v=i;
			if (!out_stream) {Logi ("Failed Allocating output stream\n");
			ret = Averror_unknown;
		Goto end;
		} videoindex_out=out_stream->index; Copy the settings of Avcodeccontext if (Avcodec_copy_context (Out_stream->codec, In_stream->codec) < 0) {L
			OGI ("Failed to copy context from input to output stream codec context\n");
		Goto end;
		} out_stream->codec->codec_tag = 0; if (Ofmt_ctx->oformat->flags & Avfmt_globalheader) out_stream->codec->flags |= CODEC_FLAG_GLOBAL_
		HEADER;
		Break (i = 0; i < ifmt_ctx_a->nb_streams; i++) {//create output avstream according to input avstream if (if Mt_ctx_a->streams[i]->codec->codec_type==avmedia_type_audio) {Avstream *in_stream = ifmt_ctx_a->
			Streams[i];
			Avstream *out_stream = Avformat_new_stream (Ofmt_ctx, In_stream->codec->codec); AudIoindex_a=i;
				if (!out_stream) {Logi ("Failed Allocating output stream\n");
				ret = Averror_unknown;
			Goto end;
			} audioindex_out=out_stream->index;
				Copy the settings of Avcodeccontext if (Avcodec_copy_context (Out_stream->codec, In_stream->codec) < 0) {
				Logi ("Failed to copy context from input to output stream codec context\n");
			Goto end;
			} out_stream->codec->codec_tag = 0; if (Ofmt_ctx->oformat->flags & Avfmt_globalheader) out_stream->codec->flags |= CODEC_FLAG_GLOBAL_

			HEADER;
		Break
	} logi ("==========output information==========\n");
	Av_dump_format (ofmt_ctx, 0, Out_filename, 1);
	Logi ("======================================\n"); Open output file if (!) ( Ofmt->flags & Avfmt_nofile)) {if (Avio_open (&AMP;OFMT_CTX-&GT;PB, Out_filename, Avio_flag_write) < 0) {LO
			GI ("Could not open output file '%s '", out_filename);
		Goto end; }//write File Header if (Avformat_write_header(Ofmt_ctx, NULL) < 0) {Logi ("Error occurred when opening output file\n");
	Goto end; 
//fix #if use_h264bsf avbitstreamfiltercontext* h264bsfc = Av_bitstream_filter_init ("H264_mp4toannexb"); 
#endif #if use_aacbsf avbitstreamfiltercontext* aacbsfc = Av_bitstream_filter_init ("Aac_adtstoasc");
		#endif while (1) {Avformatcontext *ifmt_ctx;
		int stream_index=0;

		Avstream *in_stream, *out_stream; Get an Avpacket if (Av_compare_ts cur_pts_v,ifmt_ctx_v->streams[videoindex_v]->time_base,cur_pts_a,ifmt_
			Ctx_a->streams[audioindex_a]->time_base) <= 0) {ifmt_ctx=ifmt_ctx_v;

			Stream_index=videoindex_out;
					if (Av_read_frame (Ifmt_ctx, &AMP;PKT) >= 0) {do{In_stream = ifmt_ctx->streams[pkt.stream_index];

					Out_stream = ofmt_ctx->streams[stream_index]; if (pkt.stream_index==videoindex_v) {//fix:no pts (Example:raw H.264)//simple Write PTS if (pkt.pts==av_ Nopts_value) {//write PTS avrational time_base1=in_stream->time_base;
							Duration between 2 frames (US) int64_t calc_duration= (double) av_time_base/av_q2d (in_stream->r_frame_rate);
							Parameters pkt.pts= (Double) (frame_index*calc_duration)/(double) (av_q2d (TIME_BASE1) *av_time_base);
							pkt.dts=pkt.pts;
							pkt.duration= (Double) calc_duration/(double) (av_q2d (TIME_BASE1) *av_time_base);
						frame_index++;
						} cur_pts_v=pkt.pts;
					Break
			}}while (Av_read_frame (Ifmt_ctx, &AMP;PKT) >= 0);
			}else{break;
			}}else{ifmt_ctx=ifmt_ctx_a;
			Stream_index=audioindex_out;
					if (Av_read_frame (Ifmt_ctx, &AMP;PKT) >= 0) {do{In_stream = ifmt_ctx->streams[pkt.stream_index];

					Out_stream = ofmt_ctx->streams[stream_index];
							if (pkt.stream_index==audioindex_a) {//fix:no pts//simple Write pts if (pkt.pts==av_nopts_value) {
							Write PTS avrational time_base1=in_stream->time_base; Duration between 2 frAmes (US) int64_t calc_duration= (double) av_time_base/av_q2d (in_stream->r_frame_rate);
							Parameters pkt.pts= (Double) (frame_index*calc_duration)/(double) (av_q2d (TIME_BASE1) *av_time_base);
							pkt.dts=pkt.pts;
							pkt.duration= (Double) calc_duration/(double) (av_q2d (TIME_BASE1) *av_time_base);
						frame_index++;

						} cur_pts_a=pkt.pts;
					Break
			}}while (Av_read_frame (Ifmt_ctx, &AMP;PKT) >= 0);
			}else{break; }//fix:bitstream Filter #if use_h264bsf av_bitstream_filter_filter (H264BSFC, In_stream->codec, NULL, &AMP;PK
T.data, &pkt.size, Pkt.data, pkt.size, 0); #endif #if USE_AACBSF av_bitstream_filter_filter (AACBSFC, Out_stream->codec, NULL, &pkt.data, &pkt.size,
Pkt.data, pkt.size, 0); #endif//convert Pts/dts pkt.pts = Av_rescale_q_rnd (pkt.pts, In_stream->time_base, Out_stream->time_base, AV_ Round_near_inf|
		Av_round_pass_minmax)); Pkt.dts = Av_rescale_q_rnd (Pkt.dts, In_stream->tiMe_base, Out_stream->time_base, (av_round_near_inf|
		Av_round_pass_minmax));
		Pkt.duration = Av_rescale_q (pkt.duration, In_stream->time_base, out_stream->time_base);
		Pkt.pos =-1;

		Pkt.stream_index=stream_index; Logi ("Write 1 Packet.")
		Size:%5d ", pkt.size);
		Logi ("Write 1 packet.pts--->%11d", pkt.pts);
			Write if (Av_interleaved_write_frame (Ofmt_ctx, &AMP;PKT) < 0) {Logi ("Error muxing packet\n");
		Break

	} av_free_packet (&AMP;PKT);

}//write File Trailer Av_write_trailer (OFMT_CTX);
#if USE_H264BSF Av_bitstream_filter_close (H264BSFC);
#endif #if USE_AACBSF av_bitstream_filter_close (AACBSFC);
	#endif end:avformat_close_input (&AMP;IFMT_CTX_V);
	Avformat_close_input (&ifmt_ctx_a); /* Close Output */if (Ofmt_ctx &&!)
	Ofmt->flags & Avfmt_nofile)) Avio_close (OFMT_CTX-&GT;PB);
	Avformat_free_context (OFMT_CTX);
		if (Ret < 0 && ret!= averror_eof) {logi ("Error occurred.\n");
	return-1;
return 0;
 }

Android.mk

Local_path: = $ (call My-dir) $ (Warning $ (local_path)) include $ (clear_vars) Local_module: =avcodec-55 local_src_files
 
: =lib/libavcodec-55.so local_export_c_includes: = $ (Local_path)/libavcodec include $ (prebuilt_shared_library) Include $ (clear_vars) Local_module: =avfilter-3 local_src_files: =lib/libavfilter-3.so local_export_c_includes: = $ ( Local_path)/libavfilter include $ (prebuilt_shared_library) include $ (clear_vars) Local_module: =avformat-55 LOCAL_SRC _files: =lib/libavformat-55.so local_export_c_includes: = $ (Local_path)/libavformat include $ (prebuilt_shared_  LIBRARY) include $ (clear_vars) Local_module: = avutil-52 local_src_files: =lib/libavutil-52.so local_export_c_includes : = $ (Local_path)/libavutil include $ (prebuilt_shared_library) include $ (clear_vars) Local_module: = swresample-0 Local _src_files: =lib/libswresample-0.so local_export_c_includes: = $ (Local_path)/libswresample include $ (PREBUILT_SHARED
_library) include $ (clear_vars) Local_module: = Swscale-2Local_src_files: =lib/libswscale-2.so local_export_c_includes: = $ (Local_path)/libswscale include $ (PREBUILT_SHARED_ LIBRARY) include $ (clear_vars) Local_module: =ffmpeg local_src_files: =MUXERANDROID.C # Local_export_c_includes: = $ (LO Cal_path)/include local_ldlibs: =-llog-ljnigraphics-lz-landroid local_shared_libraries:= libavcodec-55
 3 libavformat-55 libavutil-52 libswscale-2 libswresample-0 include $ (build_shared_library)


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.