From: Alex Converse Date: Wed, 17 Aug 2011 01:43:27 +0000 (-0700) Subject: avconv: Factorize video resampling. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=87ef060c3b0425d520ae42cd3dd61dd6574a5c26;p=coroid%2Flibav_saccubus.git avconv: Factorize video resampling. --- diff --git a/avconv.c b/avconv.c index 50fa1a70d..6fa3e9426 100644 --- a/avconv.c +++ b/avconv.c @@ -1030,58 +1030,14 @@ static void do_subtitle_out(AVFormatContext *s, static int bit_buffer_size= 1024*256; static uint8_t *bit_buffer= NULL; -static void do_video_out(AVFormatContext *s, - OutputStream *ost, - InputStream *ist, - AVFrame *in_picture, - int *frame_size, float quality) +static void do_video_resample(OutputStream *ost, + InputStream *ist, + AVFrame *in_picture, + AVFrame **out_picture) { - int nb_frames, i, ret, resample_changed; - AVFrame *final_picture, *formatted_picture; - AVCodecContext *enc, *dec; - double sync_ipts; - - enc = ost->st->codec; - dec = ist->st->codec; - - sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base); - - /* by default, we output a single frame */ - nb_frames = 1; - - *frame_size = 0; - - if(video_sync_method){ - double vdelta = sync_ipts - ost->sync_opts; - //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c - if (vdelta < -1.1) - nb_frames = 0; - else if (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS))){ - if(vdelta<=-0.6){ - nb_frames=0; - }else if(vdelta>0.6) - ost->sync_opts= lrintf(sync_ipts); - }else if (vdelta > 1.1) - nb_frames = lrintf(vdelta); -//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames); - if (nb_frames == 0){ - ++nb_frames_drop; - if (verbose>2) - fprintf(stderr, "*** drop!\n"); - }else if (nb_frames > 1) { - nb_frames_dup += nb_frames - 1; - if (verbose>2) - fprintf(stderr, "*** %d dup!\n", nb_frames-1); - } - }else - ost->sync_opts= lrintf(sync_ipts); - - nb_frames= FFMIN(nb_frames, max_frames[AVMEDIA_TYPE_VIDEO] - ost->frame_number); - if (nb_frames <= 0) - return; - - formatted_picture = in_picture; - final_picture = formatted_picture; + int resample_changed = 0; + AVCodecContext *dec = ist->st->codec; + *out_picture = in_picture; resample_changed = ost->resample_width != dec->width || ost->resample_height != dec->height || @@ -1099,7 +1055,7 @@ static void do_video_out(AVFormatContext *s, #if !CONFIG_AVFILTER if (ost->video_resample) { - final_picture = &ost->pict_tmp; + *out_picture = &ost->pict_tmp; if (resample_changed) { /* initialize a new scaler context */ sws_freeContext(ost->img_resample_ctx); @@ -1116,8 +1072,8 @@ static void do_video_out(AVFormatContext *s, exit_program(1); } } - sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize, - 0, ost->resample_height, final_picture->data, final_picture->linesize); + sws_scale(ost->img_resample_ctx, in_picture->data, in_picture->linesize, + 0, ost->resample_height, (*out_picture)->data, (*out_picture)->linesize); } #else if (resample_changed) { @@ -1133,6 +1089,60 @@ static void do_video_out(AVFormatContext *s, ost->resample_height = dec->height; ost->resample_pix_fmt = dec->pix_fmt; } +} + + +static void do_video_out(AVFormatContext *s, + OutputStream *ost, + InputStream *ist, + AVFrame *in_picture, + int *frame_size, float quality) +{ + int nb_frames, i, ret; + AVFrame *final_picture; + AVCodecContext *enc, *dec; + double sync_ipts; + + enc = ost->st->codec; + dec = ist->st->codec; + + sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base); + + /* by default, we output a single frame */ + nb_frames = 1; + + *frame_size = 0; + + if(video_sync_method){ + double vdelta = sync_ipts - ost->sync_opts; + //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c + if (vdelta < -1.1) + nb_frames = 0; + else if (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS))){ + if(vdelta<=-0.6){ + nb_frames=0; + }else if(vdelta>0.6) + ost->sync_opts= lrintf(sync_ipts); + }else if (vdelta > 1.1) + nb_frames = lrintf(vdelta); +//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames); + if (nb_frames == 0){ + ++nb_frames_drop; + if (verbose>2) + fprintf(stderr, "*** drop!\n"); + }else if (nb_frames > 1) { + nb_frames_dup += nb_frames - 1; + if (verbose>2) + fprintf(stderr, "*** %d dup!\n", nb_frames-1); + } + }else + ost->sync_opts= lrintf(sync_ipts); + + nb_frames= FFMIN(nb_frames, max_frames[AVMEDIA_TYPE_VIDEO] - ost->frame_number); + if (nb_frames <= 0) + return; + + do_video_resample(ost, ist, in_picture, &final_picture); /* duplicates frame if needed */ for(i=0;i