Commit 87ef060c authored by Alex Converse's avatar Alex Converse

avconv: Factorize video resampling.

parent 9be3c124
...@@ -1030,58 +1030,14 @@ static void do_subtitle_out(AVFormatContext *s, ...@@ -1030,58 +1030,14 @@ static void do_subtitle_out(AVFormatContext *s,
static int bit_buffer_size= 1024*256; static int bit_buffer_size= 1024*256;
static uint8_t *bit_buffer= NULL; static uint8_t *bit_buffer= NULL;
static void do_video_out(AVFormatContext *s, static void do_video_resample(OutputStream *ost,
OutputStream *ost, InputStream *ist,
InputStream *ist, AVFrame *in_picture,
AVFrame *in_picture, AVFrame **out_picture)
int *frame_size, float quality)
{ {
int nb_frames, i, ret, resample_changed; int resample_changed = 0;
AVFrame *final_picture, *formatted_picture; AVCodecContext *dec = ist->st->codec;
AVCodecContext *enc, *dec; *out_picture = in_picture;
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;
resample_changed = ost->resample_width != dec->width || resample_changed = ost->resample_width != dec->width ||
ost->resample_height != dec->height || ost->resample_height != dec->height ||
...@@ -1099,7 +1055,7 @@ static void do_video_out(AVFormatContext *s, ...@@ -1099,7 +1055,7 @@ static void do_video_out(AVFormatContext *s,
#if !CONFIG_AVFILTER #if !CONFIG_AVFILTER
if (ost->video_resample) { if (ost->video_resample) {
final_picture = &ost->pict_tmp; *out_picture = &ost->pict_tmp;
if (resample_changed) { if (resample_changed) {
/* initialize a new scaler context */ /* initialize a new scaler context */
sws_freeContext(ost->img_resample_ctx); sws_freeContext(ost->img_resample_ctx);
...@@ -1116,8 +1072,8 @@ static void do_video_out(AVFormatContext *s, ...@@ -1116,8 +1072,8 @@ static void do_video_out(AVFormatContext *s,
exit_program(1); exit_program(1);
} }
} }
sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize, sws_scale(ost->img_resample_ctx, in_picture->data, in_picture->linesize,
0, ost->resample_height, final_picture->data, final_picture->linesize); 0, ost->resample_height, (*out_picture)->data, (*out_picture)->linesize);
} }
#else #else
if (resample_changed) { if (resample_changed) {
...@@ -1133,6 +1089,60 @@ static void do_video_out(AVFormatContext *s, ...@@ -1133,6 +1089,60 @@ static void do_video_out(AVFormatContext *s,
ost->resample_height = dec->height; ost->resample_height = dec->height;
ost->resample_pix_fmt = dec->pix_fmt; 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 */ /* duplicates frame if needed */
for(i=0;i<nb_frames;i++) { for(i=0;i<nb_frames;i++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment