FFmpeg Simple transcoding Program--Video editing

Source: Internet
Author: User

Study the Thunder God's article, the mousse person shares the spirit, feels its die young and dies, greatly sighs. He has shared a transcoding program, the simplest transcoding program based on FFmpeg, which uses filter (referring to the process in ffmpeg.c), and has said he wants to write a version that does not need filter, but does not have a chance. happen to work in the relevant ffmpeg processing content, so incompatible, write this article.

Related processes:

1. Open the input file

2. Open the output file

3. Setting the decoding environment

4. Setting output stream Information

5. Setting the Encoding environment

6. Turn on input stream loop read, decode and encode write

7.fflush Decoding and encoding CTX

8. Close the file

The code of this article, in order to support video precise editing, because of the GOP keyframe problem, need to use decoding and re-encoding, in the encoding of time to do the calibration

How to use:

./mycut Input Output start end

For example, intercept video for 1-10 seconds:

The code is as follows:

Mycut.cppextern "C" {#include <libavutil/time.h> #include <libavutil/timestamp.h> #include < libavformat/avformat.h> #include <libavformat/avio.h> #include <libavfilter/avfiltergraph.h># Include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> #include <libavutil/opt.h># Include <libavutil/imgutils.h> #include <sys/types.h> #include <unistd.h> #include <sys/socket.h > #include <arpa/inet.h> #include <strings.h> #include <stdio.h> #include <sys/stat.h># Include <fcntl.h> #include <errno.h> #include <sys/file.h> #include <signal.h> #include <sys /wait.h> #include <time.h>//time_t, TM, Time, localtime, strftime#include <sys/time.h>//time_t, TM, Time , localtime, strftime} #define Time_den 1000//Returns The local date/time formatted as 2014-03-19 11:11:52char* Getformatt Edtime (void);//Remove path from Filename#define __short_file__ (STRRCHR (__file__, '/')? sTRRCHR (__file__, '/') + 1: __file__)//Main log macro//#define __LOG__ (format, loglevel, ...) printf ("%s%-5s [%s] [%s:%d  ] "format" \ n ", Getformattedtime (), LogLevel, __func__, __short_file__, __line__, # # __va_args__) #define __LOG__ (format, LogLevel, ...) printf ("%ld%-5s [%s] [%s:%d]" format "\ n", Current_timestamp (), LogLevel, __func__, __short_file__, __line__, # # __va_ar GS__)//specific log macros with #define LOGDEBUG (format, ...) __log__ (format, "DEBUG", # # __va_args__) #define Logwarn (for Mat, ...) __LOG__ (format, "WARN", # # __va_args__) #define LOGERROR (format, ...) __log__ (format, "ERROR", # # __VA_ARGS__) #define Loginfo (format, ...) __log__ (format, "INFO", # # __va_args__)//Returns The local date/time formatted as 2014-03-19 11:11:5    2char* getformattedtime (void) {time_t rawtime;    struct tm* timeinfo;    Time (&rawtime);    Timeinfo = LocalTime (&rawtime);    Must is static, otherwise won ' t work static char _retval[26]; Strftime (_RetVal, sizeof (_retval), "%y-%m-%d%h:%m:%s ", timeinfo); return _retval;}     Long Long Current_timestamp () {struct Timeval te; Gettimeofday (&te, NULL); Get current time long long milliseconds = Te.tv_sec*1000ll + te.tv_usec/1000;    Calculate milliseconds//printf ("milliseconds:%lld\n", milliseconds); return milliseconds;} static int encode_and_save_pkt (Avcodeccontext *enc_ctx, Avformatcontext *ofmt_ctx, Avstream *out_stream) {AVPacket enc_    Pkt    Av_init_packet (&AMP;ENC_PKT);    Enc_pkt.data = NULL;    enc_pkt.size = 0;    int ret = 0;        while (ret >= 0) {ret = Avcodec_receive_packet (Enc_ctx, &AMP;ENC_PKT);            if (ret = = Averror (eagain) | | ret = = averror_eof) {ret = 0;        Break            } else if (Ret < 0) {printf ("[Avcodec_receive_packet]error during encoding, ret:%d\n", ret);        Break        } logdebug ("Encode type:%d pts:%d dts:%d\n", Enc_ctx->codec_type, Enc_pkt.pts, Enc_pkt.dts); /* Rescale output packet timestamp values from codec to stream Timebase */av_packet_rescale_ts (&AMP;ENC_PKT, enc_ct        X->time_base, out_stream->time_base);        Enc_pkt.stream_index = out_stream->index;        ret = Av_interleaved_write_frame (Ofmt_ctx, &AMP;ENC_PKT);            if (Ret < 0) {printf ("Write frame error, ret:%d\n", ret);        Break    } av_packet_unref (&AMP;ENC_PKT); } return ret;} static int Decode_and_send_frame (Avcodeccontext *dec_ctx, avcodeccontext *enc_ctx, int start, int end) {Avframe *frame    = Av_frame_alloc ();    int ret = 0;        while (ret >= 0) {ret = Avcodec_receive_frame (dec_ctx, frame);            if (ret = = Averror (eagain) | | ret = = averror_eof) {ret = 0;        Break            } else if (Ret < 0) {printf ("Error while receiving a frame from the decoder");        Break        } int pts = frame->pts; Logdebug ("Decode type:%d pts:%d\n ", Dec_ctx->codec_type, pts); if (pts < Start*time_den) | | (pts > End*time_den))        {//Data clipping continue;        } frame->pict_type = Av_picture_type_none;        Modify pts frame->pts = Pts-start*time_den;        printf ("pts:%d\n", frame->pts);        ret = Avcodec_send_frame (enc_ctx, frame);            if (Ret < 0) {printf ("Error sending a frame for encoding\n");        Break    }} av_frame_free (&frame); return ret;} static int Open_decodec_context (int *stream_idx, Avcodeccontext **dec_ctx, Avformatcontext    *fmt_ctx, enum Avmediatype type) {int ret, stream_index;    Avstream *st;    Avcodec *dec = NULL;    Avdictionary *opts = NULL;    ret = Av_find_best_stream (Fmt_ctx, type,-1,-1, &dec, 0); if (Ret < 0) {fprintf (stderr, "Could not find%s stream in input file \ n", Av_get_media_type_        String (type)); return ret;        } else {stream_index = ret;        St = fmt_ctx->streams[stream_index];        /* Allocate A codec context for the decoder */*dec_ctx = AVCODEC_ALLOC_CONTEXT3 (dec); if (!*dec_ctx) {fprintf (stderr, "Failed to allocate the%s codec context\n", av_get_            Media_type_string (type));        Return Averror (ENOMEM); }/* Copy codec parameters from input stream to output codec context */if (ret = Avcodec_parameters_to_con Text (*dec_ctx, st->codecpar)) < 0) {fprintf (stderr, "Failed to copy%s codec parameters to decode            R context\n ", Av_get_media_type_string (type));        return ret; } if ((*dec_ctx)->codec_type = = Avmedia_type_video) (*dec_ctx)->framerate = AV_GUESS_FRAME_RATE (FM        T_ctx, St, NULL); /* Init the decoders, with or without reference counting */Av_dict_set_int (&opts, "Refcounted_frames", 1, 0);        if (ret = Avcodec_open2 (*dec_ctx, Dec, &opts)) < 0) {fprintf (stderr, "Failed to open%s            Codec\n ", av_get_media_type_string (type));        return ret;    } *stream_idx = Stream_index; } return 0;} static int set_encode_option (Avcodeccontext *dec_ctx, avdictionary **opt) {const char *profile = Avcodec_profile_name (d    ec_ctx->codec_id, Dec_ctx->profile);        if (profile) {if (!strcasecmp (Profiles, "high")) {Av_dict_set (opt, ' profile ', "high", 0);    }} else {Av_dict_set (opt, "profile", "main", 0);    } av_dict_set (OPT, "threads", "16", 0);    Av_dict_set (OPT, "preset", "slow", 0);    Av_dict_set (OPT, "level", "4.0", 0); return 0;} static int Open_encodec_context (int stream_index, Avcodeccontext **oenc_ctx, Avformatcontext *fmt_ctx, enum AVMediaType    Type) {int ret;    Avstream *st;    Avcodec *encoder = NULL;    Avdictionary *opts = NULL; AvcodeccontExt *enc_ctx;    St = fmt_ctx->streams[stream_index];    /* Find encoder for the stream */encoder = Avcodec_find_encoder (st->codecpar->codec_id);        if (!encoder) {fprintf (stderr, "Failed to find%s codec\n", av_get_media_type_string (type));    Return Averror (EINVAL);    } Enc_ctx = AVCODEC_ALLOC_CONTEXT3 (encoder);        if (!enc_ctx) {printf ("Failed to allocate the encoder context\n");    Return Averror (ENOMEM);    } Avcodeccontext *dec_ctx = st->codec;        if (type = = Avmedia_type_video) {enc_ctx->height = dec_ctx->height;        Enc_ctx->width = dec_ctx->width;        Enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;        Enc_ctx->bit_rate = dec_ctx->bit_rate;        Enc_ctx->rc_max_rate = dec_ctx->bit_rate;        Enc_ctx->rc_buffer_size = dec_ctx->bit_rate;        enc_ctx->bit_rate_tolerance = 0; Use yuv420p enc_ctx->pix_fmt = av_pix_fmt_yuv420p;        Set frame rate Enc_ctx->time_base.num = 1;        Enc_ctx->time_base.den = Time_den;        Enc_ctx->flags |= Av_codec_flag_global_header;        Enc_ctx->has_b_frames = false;        Enc_ctx->max_b_frames = 0;        Enc_ctx->gop_size = 120;    Set_encode_option (Dec_ctx, &opts);        } else if (type = = Avmedia_type_audio) {enc_ctx->sample_rate = dec_ctx->sample_rate;        Enc_ctx->channel_layout = dec_ctx->channel_layout;        Enc_ctx->channels = Av_get_channel_layout_nb_channels (enc_ctx->channel_layout);        /* Take first format from List of supported formats */ENC_CTX-&GT;SAMPLE_FMT = encoder->sample_fmts[0];        Enc_ctx->time_base = (avrational) {1, time_den};        Enc_ctx->bit_rate = dec_ctx->bit_rate;    Enc_ctx->flags |= Av_codec_flag_global_header;        } else {ret = Avcodec_copy_context (Enc_ctx, St->codec);     if (Ret < 0) {       fprintf (stderr, "Failed to copy context from input to output stream codec context\n");        return ret; }} if (ret = Avcodec_open2 (enc_ctx, encoder, &opts)) < 0) {fprintf (stderr, "Failed to open%s co        Dec\n ", av_get_media_type_string (type));    return ret;    } *oenc_ctx = Enc_ctx; return 0;}    int Test_cut (char *input_file, char *output_file, int start, int end) {int ret = 0;    Av_register_all ();    Input stream Avformatcontext *ifmt_ctx = NULL;    Avcodeccontext *video_dec_ctx = NULL;    Avcodeccontext *audio_dec_ctx = NULL;    char *flv_name = input_file;    int video_stream_idx = 0;    int audio_stream_idx = 1;    Output stream Avformatcontext *ofmt_ctx = NULL;    Avcodeccontext *audio_enc_ctx = NULL;    Avcodeccontext *video_enc_ctx = NULL; if (ret = Avformat_open_input (&ifmt_ctx, flv_name, 0, 0)) < 0) {printf ("Could not open input file '%s '        Ret:%d\n ", Flv_name, ret);    Goto end; } if(ret = avformat_find_stream_info (ifmt_ctx, 0)) < 0)        {printf ("Failed to retrieve input stream information");    Goto end;        } if (Open_decodec_context (&video_stream_idx, &video_dec_ctx, Ifmt_ctx, Avmedia_type_video) < 0) {        printf ("Fail to open vedio decode context, ret:%d\n", ret);    Goto end;        } if (Open_decodec_context (&audio_stream_idx, &audio_dec_ctx, Ifmt_ctx, Avmedia_type_audio) < 0) {        printf ("Fail to open audio decode context, ret:%d\n", ret);    Goto end;    } av_dump_format (Ifmt_ctx, 0, input_file, 0);    Set Output avformat_alloc_output_context2 (&AMP;OFMT_CTX, NULL, NULL, output_file);        if (!ofmt_ctx) {printf ("Can not open ouout context");    Goto end;    }//Video stream Avstream *out_stream;    Out_stream = Avformat_new_stream (Ofmt_ctx, NULL);        if (!out_stream) {printf ("Failed Allocating output stream\n");        ret = Averror_unknown;    Goto end; }   if (ret = Open_encodec_context (Video_stream_idx, &video_enc_ctx, Ifmt_ctx, Avmedia_type_video)) < 0) {        printf ("Video enc CTX init err\n");    Goto end;    } ret = Avcodec_parameters_from_context (Out_stream->codecpar, video_enc_ctx);        if (Ret < 0) {printf ("Failed to copy codec parameters\n");    Goto end;    } video_enc_ctx->flags |= Av_codec_flag_global_header;    Out_stream->time_base = video_enc_ctx->time_base;    Out_stream->codecpar->codec_tag = 0;    Audio Stream out_stream = Avformat_new_stream (Ofmt_ctx, NULL);        if (!out_stream) {printf ("Failed Allocating output stream\n");        ret = Averror_unknown;    Goto end;        } if (ret = Open_encodec_context (Audio_stream_idx, &audio_enc_ctx, Ifmt_ctx, Avmedia_type_audio)) < 0) {        printf ("Audio enc CTX init err\n");    Goto end;    } ret = Avcodec_parameters_from_context (Out_stream->codecpar, audio_enc_ctx); if (reT < 0) {printf ("Failed to copy codec parameters\n");    Goto end;    } audio_enc_ctx->flags |= Av_codec_flag_global_header;    Out_stream->time_base = audio_enc_ctx->time_base;    Out_stream->codecpar->codec_tag = 0;    Av_dump_format (ofmt_ctx, 0, output_file, 1); Open File if (! ( Ofmt_ctx->oformat->flags & avfmt_nofile) {ret = Avio_open (&AMP;OFMT_CTX-&GT;PB, Output_file, AVIO_FL        Ag_write);            if (Ret < 0) {printf ("Could not open output file '%s ' \ n", output_file);        Goto end;    }} ret = Avformat_write_header (Ofmt_ctx, NULL);        if (Ret < 0) {printf ("Error occurred when opening output file\n");    Goto end;    } Avpacket flv_pkt;    int stream_index;        while (1) {Avpacket *pkt = &flv_pkt;        ret = Av_read_frame (Ifmt_ctx, PKT);        if (Ret < 0) {break; } if (Pkt->stream_index = = Video_stream_idx && (Pkt->flags & Av_pkt_flag_key)) {printf ("Pkt.dts =%ld pkt.pts =%ld Pkt.stream_index =%d        is key frame\n ", Pkt->dts, Pkt->pts, Pkt->stream_index);        } Stream_index = pkt->stream_index;            if (Pkt->stream_index = = video_stream_idx) {ret = Avcodec_send_packet (Video_dec_ctx, PKT);            Logdebug ("Read type:%d pts:%d dts:%d\n", Video_dec_ctx->codec_type, Pkt->pts, Pkt->dts);            ret = Decode_and_send_frame (Video_dec_ctx, Video_enc_ctx, start, end);            ret = ENCODE_AND_SAVE_PKT (Video_enc_ctx, Ofmt_ctx, ofmt_ctx->streams[0]);            if (Ret < 0) {printf ("Re encode video error, ret:%d\n", ret); }} else if (Pkt->stream_index = = audio_stream_idx) {ret = Avcodec_send_packet (audio_d            Ec_ctx, PKT); Logdebug ("Read type:%d pts:%d dts:%d\n", Audio_dec_ctx->codec_type, Pkt->pts, Pkt->dts);           ret = Decode_and_send_frame (Audio_dec_ctx, Audio_enc_ctx, start, end);            ret = ENCODE_AND_SAVE_PKT (Audio_enc_ctx, Ofmt_ctx, ofmt_ctx->streams[1]);            if (Ret < 0) {printf ("Re encode audio error, ret:%d\n", ret);    }} av_packet_unref (PKT);    }//Fflush//Fflush encode Avcodec_send_packet (Video_dec_ctx, NULL);    Decode_and_send_frame (Video_dec_ctx, Video_enc_ctx, start, end);    Avcodec_send_packet (Audio_dec_ctx, NULL);    Decode_and_send_frame (Audio_dec_ctx, Audio_enc_ctx, start, end);    Fflush decode Avcodec_send_frame (Video_enc_ctx, NULL);    ENCODE_AND_SAVE_PKT (Video_enc_ctx, Ofmt_ctx, ofmt_ctx->streams[0]);    Avcodec_send_frame (Audio_enc_ctx, NULL);    ENCODE_AND_SAVE_PKT (Audio_enc_ctx, Ofmt_ctx, ofmt_ctx->streams[1]);    Logdebug ("Stream end\n");    Av_write_trailer (OFMT_CTX); End:avformat_close_input (&AMP;IFMT_CTX); if (Ofmt_ctx &&!) ( ofmt_ctx->oformat->flags & Avfmt_nofile)) avio_closep (&AMP;OFMT_CTX-&GT;PB);    Avformat_free_context (OFMT_CTX);    Avcodec_free_context (&AMP;VIDEO_DEC_CTX);    Avcodec_free_context (&AMP;AUDIO_DEC_CTX); return ret;}    int main (int argc, char **argv) {int ret = 0;        if (ARGC < 5) {printf ("Usage:%s input output start end \ n", argv[0]);    return 1;    } char *input_file = argv[1];    Char *output_file = argv[2];    int start = Atoi (Argv[3]);    int end = Atoi (Argv[4]);    ret = Test_cut (input_file, output_file, start, end); return ret;}

  

FFmpeg Simple transcoding Program--Video editing

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.