The simplest FFMPEG-based Encapsulation Format processing: demuxer)

Source: Internet
Author: User
Tags file url
I plan to record examples of FFMPEG-based Encapsulation Format processing. Including separation, reuse, and Encapsulation Format Conversion of audio and video. This is Article 2nd.

This document records a video/audio Splitter (simplest FFMPEG demuxer) based on FFMPEG ). The demuxer separates the compressed video data (for example, H.264) and compressed audio data (for example, AAC) in the encapsulated format data (for example, MKV .. Encoding and decoding are not involved in this process.


The recorded program can encapsulate an mpeg2ts video file (where the video is encoded as H. 264, audio encoding is AAC) separated into two files: one H. A 264 encoded video code stream file, An AAC encoded audio code stream file.
In the previous article, record a simple version of the video/audio splitter. Compared with the separators in the previous article, the separators recorded in this article are much more complicated. Compared with the splitter of the simple version, the learning is more difficult. However, this splitter can well process various formats supported by FFMPEG (for example, separating AAC audio streams) and has better practicability.

Flowchart
Shows the program process. We can see from the flowchart that three avformatcontext are initialized, one of which is used for input, and the other two are used for video output and audio output respectively. After the three avformatcontext initialization, you can use the avcodec_copy_context () function to copy the input video/audio parameters to the avcodeccontext structure of the output video/audio. Finally, avpacket is obtained through av_read_frame (). You can use av_interleaved_write_frame () to write data to different output files based on the avpacket type.

PS: for H.264 in some encapsulation formats (such as MP4/FLV/MKV), bitstream filter named "h1__mp4to1_ B" is required. This is already described in detail in the previous article "the simplest FFMPEG-based Encapsulation Format processing: demuxer-simple.

Briefly introduce the significance of each important function in the process:
Avformat_open_input (): Open the input file.
Avcodec_copy_context (): assign a value to the avcodeccontext parameter.
Avformat_alloc_output_context2 (): Initialize the output file.
Avio_open (): Open the output file.
Avformat_write_header (): Write the file header.
Av_read_frame (): read an avpacket from the input file.
Av_interleaved_write_frame (): Write an avpacket to the output file.
Av_write_trailer (): The end of the written file.

Paste the code below:

/*** the simplest FFMPEG-based audio/video splitter ** simplest FFMPEG demuxer ** Lei Xiaohua * [email protected] * media University of China/Digital TV technology * communication University of China/Digital TV technology * http://blog.csdn.net/leixiaohua1020 ** this program can separate the video stream data in the encapsulated format from the audio stream data. * In this example, the mpeg2ts file is separated to obtain the H.264 video stream file and aac * audio stream file. ** This software split a media file (in container such as * MKV, FLV, Avi ...) to video and audio bitstream. * In this example, it Demux A mpeg2ts file to H. 264 bitstream * and aac bitstream. */# include extern "C" {# include "libavformat/avformat. H "};/* fix: H. 264 in some container format (FLV, MP4, MKV etc .) need "hsf-_mp4tow. B" bitstream filter (BSF) * Add SPS, PPs in front of IDR frame * Add start code ("0, 0, 1") in front of naluh.264 in some iner (mpeg2ts) Don't need this BSF. * // '1': Use H. 264 bitstream filter # define use_hsf-bsf 0int main (INT argc, char * argv []) {avoutputformat * ofmt_a = NULL, * ofmt_v = NULL; // The input corresponds to an avformatcontext, the output corresponds to an avformatcontext // (input avformatcontext and output avformatcontext) avformatcontext * ifmt_ctx = NULL, * ofmt_ctx_a = NULL, * ofmt_ctx_v = NUL L; avpacket Pkt; int ret, I; char * in_filename = "cuc_ieschool.ts"; // input file name (Input File URL) // char * in_filename = "cuc_ieschool.mkv "; char * out_filename_v = "inline"; // output file URL // char * out_filename_a = "inline"; char * out_filename_a = "cuc_ieschool.aac"; av_register_all (); // input (input) if (ret = avformat_open_input (& ifmt_ctx, in_filename, 0, 0) <0) {printf ("cocould not ope N input file. "); goto end;} If (ret = avformat_find_stream_info (ifmt_ctx, 0) <0) {printf (" failed to retrieve input stream information "); goto end ;} // output (output) avformat_alloc_output_context2 (& ofmt_ctx_v, null, null, out_filename_v); If (! Ofmt_ctx_v) {printf ("cocould not create output context \ n"); ret = averror_unknown; goto end;} ofmt_v = ofmt_ctx_v-> oformat; encode (& ofmt_ctx_a, null, null, out_filename_a); If (! Ofmt_ctx_a) {printf ("cocould not create output context \ n"); ret = averror_unknown; goto end;} ofmt_a = ofmt_ctx_a-> oformat; int videoindex =-1, audioindex =-1; for (I = 0; I nb_streams; I ++) {// create an output stream based on the input stream (create output avstream according to input avstream) avformatcontext * ofmt_ctx; avstream * in_stream = ifmt_ctx-> streams [I]; avstream * out_stream = NULL; If (ifmt_ctx-> streams [I]-> codec-> codec_type = Vmedia_type_video) {videoindex = I; out_stream = avformat_new_stream (ofmt_ctx_v, in_stream-> codec); ofmt_ctx = ofmt_ctx_v ;} else if (ifmt_ctx-> streams [I]-> codec-> codec_type = bytes) {audioindex = I; out_stream = avformat_new_stream (ofmt_ctx_a, in_stream-> codec ); ofmt_ctx = ofmt_ctx_a;} else {break;} If (! Out_stream) {printf ("failed allocating output stream \ n"); ret = averror_unknown; goto end;} // copy avcodeccontext settings (copy the settings of avcodeccontext) if (avcodec_copy_context (out_stream-> codec, in_stream-> codec) <0) {printf ("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-> Co Dec-> flags | = codec_flag_global_header ;} // dump format ---------------- printf ("\ ninput video =======================\ n "); av_dump_format (ifmt_ctx, 0, in_filename, 0 ); printf ("\ noutput video ===============================\ N "); av_dump_format (ofmt_ctx_v, 0, out_filename_v, 1 ); printf ("\ noutput audio ===============================\ N "); av_dump_format (ofmt_ctx_a, 0, out_filename_a, 1); printf ("\ n ================ =================================\ N "); // open the output file (Open output file) if (! (Ofmt_v-> flags & avfmt_nofile) {If (avio_open (& ofmt_ctx_v-> Pb, out_filename_v, avio_flag_write) <0) {printf ("cocould not open output file '% S'", out_filename_v); goto end ;}} if (! (Ofmt_a-> flags & avfmt_nofile) {If (avio_open (& ofmt_ctx_a-> Pb, out_filename_a, avio_flag_write) <0) {printf ("cocould not open output file '% S'", out_filename_a); goto end ;}// Write File Header (Write File Header) if (avformat_write_header (ofmt_ctx_v, null) <0) {printf ("error occurred when opening video output file \ n"); goto end;} If (avformat_write_header (ofmt_ctx_a, null) <0) {printf ("error occurred when openi Ng audio output file \ n "); goto end ;}# if needed * hsf-bsfc = av_bitstream_filter_init (" hsf-_mp4to1_ B "); # endifint frame_index = 0; while (1) {avformatcontext * ofmt_ctx; avstream * in_stream, * out_stream; // obtain an avpacket (get an avpacket) if (av_read_frame (ifmt_ctx, & Pkt) <0) break; in_stream = ifmt_ctx-> streams [Pkt. stream_index]; If (Pkt. stream_index = videoindex) {out_stream = ofmt _ Ctx_v-> streams [0]; ofmt_ctx = ofmt_ctx_v; printf ("write Video packet. size: % d \ tpts: % d \ n ", Pkt. size, Pkt. PTS); # If use_hsf-bsfav_bitstream_filter_filter (hsf-bsfc, in_stream-> codec, null, & Pkt. data, & Pkt. size, Pkt. data, Pkt. size, 0); # endif} else if (Pkt. stream_index = audioindex) {out_stream = ofmt_ctx_a-> streams [0]; ofmt_ctx = ofmt_ctx_a; printf ("Write audio packet. size: % d \ tpts: % d \ n ", Pkt. size, Pkt. PTS);} else {con Tinue;}/* Copy packet * // convert pts/DTS (convert pts/DTS) Pkt. PTS = av_rescale_q_rnd (Pkt. PTS, in_stream-> time_base, out_stream-> time_base, (avrounding) (av_round_near_inf | av_round_pass_minmax); Pkt. DTS = av_rescale_q_rnd (Pkt. DTS, in_stream-> time_base, out_stream-> time_base, (avrounding) (av_round_near_inf | av_round_pass_minmax); Pkt. duration = av_rescale_q (Pkt. duration, in_stream-> time_base, out_stream-> Ti Me_base); Pkt. pos =-1; Pkt. stream_index = 0; // write (write) if (av_interleaved_write_frame (ofmt_ctx, & Pkt) <0) {printf ("error muxing packet \ n"); break ;} // printf ("write % 8d frames to output file \ n", frame_index); av_free_packet (& Pkt); frame_index ++;} # If use_h1_bsfav_bitstream_filter_close (hsf-bsfc ); # endif // Write File trailer (Write File trailer) av_write_trailer (ofmt_ctx_a); av_write_trailer (ofmt_ctx_v); End: avformat_close _ Input (& ifmt_ctx);/* close output */If (ofmt_ctx_a &&! (Ofmt_a-> flags & avfmt_nofile) avio_close (ofmt_ctx_a-> Pb); If (ofmt_ctx_v &&! (Ofmt_v-> flags & avfmt_nofile) avio_close (ofmt_ctx_v-> Pb); avformat_free_context (plaintext); avformat_free_context (ofmt_ctx_v); If (Ret <0 & RET! = Averror_eof) {printf ("error occurred. \ n"); Return-1;} return 0 ;}


The result input file is:
Cuc_ieschool.ts: mpeg2ts Encapsulation Format data.


The output file is:
Cuc_ieschool.h264: H.264 video stream data.
Cuc_ieschool.aac: AAC audio code stream data.

Download the SourceForge project home page:
Https://sourceforge.net/projects/simplestffmpegformat/


Download csdn
Http://download.csdn.net/detail/leixiaohua1020/8005317


The project contains four examples:
Simplest_ffmpeg_demuxer_simple: video/audio Splitter (simplified version ).
Simplest_ffmpeg_demuxer: Specifies the audio and video splitter.
Simplest_ffmpeg_muxer: audio and video multiplexing (later articles ).
Simplest_ffmpeg_remuxer: Encapsulation Format converter (recorded ).



simplest FFMPEG-based Encapsulation Format processing: demuxer

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.