c - Cropping Square Video using FFmpeg -


updated

so trying decode mp4 file, crop video square, , re encode out mp4 file. current code there few issues it.

one video doesn't keep rotation after video has been re encoded

second frames outputted in fast video file not same length original

third there no sound

lastly , importantly need avfilter frame cropping or can done per frame resize of frame , encoded out.

const char *inputpath = "test.mp4"; const char *outpath = "cropped.mp4"; const char *outfiletype = "mp4";  static avframe *oframe = null;  static avfiltergraph *filtergraph = null;   static avfiltercontext *crop_ctx = null; static avfiltercontext *buffersink_ctx = null; static avfiltercontext *buffer_ctx = null;  int err;  int crop_video(int width, int height) {  av_register_all(); avcodec_register_all(); avfilter_register_all();  avformatcontext *inctx = null;  // open input file err = avformat_open_input(&inctx, inputpath, null, null); if (err < 0) {     printf("error @ open input in\n");     return err; }  // input file stream info err = avformat_find_stream_info(inctx, null); if (err < 0) {     printf("error @ find stream info\n");     return err; }  // info video av_dump_format(inctx, 0, inputpath, 0);  // find video input stream int vs = -1; int s; (s = 0; s < inctx->nb_streams; ++s) {     if (inctx->streams[s] && inctx->streams[s]->codec && inctx->streams[s]->codec->codec_type == avmedia_type_video) {         vs = s;         break;     } }  // check if video stream valid if (vs == -1) {     printf("error @ open video stream\n");     return -1; }  // set output format avoutputformat * outfmt = av_guess_format(outfiletype, null, null); if (!outfmt) {     printf("error @ output format\n");     return -1; }  // output context write avformatcontext *outctx = null; err = avformat_alloc_output_context2(&outctx, outfmt, null, null); if (err < 0 || !outctx) {     printf("error @ output context\n");     return err; }  // input , output stream avstream *outstrm = avformat_new_stream(outctx, null); avstream *instrm = inctx->streams[vs];  // add new codec output stream avcodec *codec = null; avcodec_get_context_defaults3(outstrm->codec, codec);  outstrm->codec->thread_count = 1;  outstrm->codec->coder_type = avmedia_type_video;  if(outctx->oformat->flags & avfmt_globalheader) {     outstrm->codec->flags |= codec_flag_global_header; }  outstrm->codec->sample_aspect_ratio = outstrm->sample_aspect_ratio = instrm->sample_aspect_ratio;  err = avio_open(&outctx->pb, outpath, avio_flag_write); if (err < 0) {     printf("error @ opening outpath\n");     return err; }  outstrm->disposition = instrm->disposition; outstrm->codec->bits_per_raw_sample = instrm->codec->bits_per_raw_sample; outstrm->codec->chroma_sample_location = instrm->codec->chroma_sample_location; outstrm->codec->codec_id = instrm->codec->codec_id; outstrm->codec->codec_type = instrm->codec->codec_type;  if (!outstrm->codec->codec_tag) {     if (! outctx->oformat->codec_tag         || av_codec_get_id (outctx->oformat->codec_tag, instrm->codec->codec_tag) == outstrm->codec->codec_id         || av_codec_get_tag(outctx->oformat->codec_tag, instrm->codec->codec_id) <= 0) {         outstrm->codec->codec_tag = instrm->codec->codec_tag;     } }  outstrm->codec->bit_rate = instrm->codec->bit_rate; outstrm->codec->rc_max_rate = instrm->codec->rc_max_rate; outstrm->codec->rc_buffer_size = instrm->codec->rc_buffer_size;  const size_t extra_size_alloc = (instrm->codec->extradata_size > 0) ? (instrm->codec->extradata_size + ff_input_buffer_padding_size) : 0;  if (extra_size_alloc) {     outstrm->codec->extradata = (uint8_t*)av_mallocz(extra_size_alloc);     memcpy( outstrm->codec->extradata, instrm->codec->extradata, instrm->codec->extradata_size); }  outstrm->codec->extradata_size = instrm->codec->extradata_size;  avrational input_time_base = instrm->time_base; avrational framerate = {25, 1}; if (instrm->r_frame_rate.num && instrm->r_frame_rate.den     && (1.0 * instrm->r_frame_rate.num / instrm->r_frame_rate.den < 1000.0)) {     framerate.num = instrm->r_frame_rate.num;     framerate.den = instrm->r_frame_rate.den; }  outstrm->r_frame_rate = framerate; outstrm->codec->time_base = instrm->codec->time_base;  outstrm->codec->pix_fmt = instrm->codec->pix_fmt; outstrm->codec->width = width; outstrm->codec->height =  height; outstrm->codec->has_b_frames =  instrm->codec->has_b_frames;  if (!outstrm->codec->sample_aspect_ratio.num) {     avrational r0 = {0, 1};     outstrm->codec->sample_aspect_ratio =     outstrm->sample_aspect_ratio =     instrm->sample_aspect_ratio.num ? instrm->sample_aspect_ratio :     instrm->codec->sample_aspect_ratio.num ?     instrm->codec->sample_aspect_ratio : r0; }  avformat_write_header(outctx, null);  filtergraph = avfilter_graph_alloc(); if (!filtergraph) {     printf("could not open filter graph");     return -1; }  avfilter *crop = avfilter_get_by_name("crop"); avfilter *buffer = avfilter_get_by_name("buffer"); avfilter *buffersink = avfilter_get_by_name("buffersink");  char args[512];  snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",          width, height, instrm->codec->pix_fmt,          instrm->codec->time_base.num, instrm->codec->time_base.den,          instrm->codec->sample_aspect_ratio.num, instrm->codec->sample_aspect_ratio.den);  err = avfilter_graph_create_filter(&buffer_ctx, buffer, null, args, null, filtergraph); if (err < 0) {     printf("error initializing buffer filter\n");     return err; }  err = avfilter_graph_create_filter(&buffersink_ctx, buffersink, null, null, null, filtergraph); if (err < 0) {     printf("unable create buffersink filter\n");     return err; } snprintf(args, sizeof(args), "%d:%d", width, height); err = avfilter_graph_create_filter(&crop_ctx, crop, null, args, null, filtergraph); if (err < 0) {     printf("error initializing crop filter\n");     return err; }  err = avfilter_link(buffer_ctx, 0, crop_ctx, 0); if (err < 0) {     printf("error linking filters\n");     return err; }  err = avfilter_link(crop_ctx, 0, buffersink_ctx, 0); if (err < 0) {     printf("error linking filters\n");     return err; }  err = avfilter_graph_config(filtergraph, null); if (err < 0) {     printf("error configuring filter graph\n");     return err; }  printf("filtergraph configured\n");  (;;) {      avpacket packet = {0};     av_init_packet(&packet);      err = averror(eagain);     while (averror(eagain) == err)         err = av_read_frame(inctx, &packet);      if (err < 0) {         if (averror_eof != err && averror(eio) != err) {             printf("eof error\n");             return 1;         } else {             break;         }     }      if (packet.stream_index == vs) {          //         //            avpacket pkt_temp_;         //            memset(&pkt_temp_, 0, sizeof(pkt_temp_));         //            avpacket *pkt_temp = &pkt_temp_;         //         //            *pkt_temp = packet;         //         //            int error, got_frame;         //            int new_packet = 1;         //         //            error = avcodec_decode_video2(instrm->codec, frame, &got_frame, pkt_temp);         //            if(error < 0) {         //                loge("error %d", error);         //            }         //         //            // if (error >= 0) {         //         //            // push video data decoded frame filtergraph         //            int err = av_buffersrc_write_frame(buffer_ctx, frame);         //            if (err < 0) {         //                loge("error writing frame buffersrc");         //                return -1;         //            }         //            // pull filtered video filtergraph         //            (;;) {         //                int err = av_buffersink_get_frame(buffersink_ctx, oframe);         //                if (err == averror_eof || err == averror(eagain))         //                    break;         //                if (err < 0) {         //                    loge("error reading buffer buffersink");         //                    return -1;         //                }         //            }         //         //            logi("output frame");          err = av_interleaved_write_frame(outctx, &packet);         if (err < 0) {             printf("error @ write frame");             return -1;         }          //}     }      av_free_packet(&packet); }  av_write_trailer(outctx); if (!(outctx->oformat->flags & avfmt_nofile) && outctx->pb)     avio_close(outctx->pb);  avformat_free_context(outctx); avformat_close_input(&inctx);  return 0; 

}

it looks looking vf_crop.

the cropcontext contains x, y, w, , h, should need crop video specific width , height.


Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -