]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/video_filter.c
Merge branch 'master' of git@git.videolan.org:vlc
[vlc] / modules / codec / ffmpeg / video_filter.c
1 /*****************************************************************************
2  * video filter: video filter doing chroma conversion and resizing
3  *               using the ffmpeg library
4  *****************************************************************************
5  * Copyright (C) 1999-2001 the VideoLAN team
6  * $Id$
7  *
8  * Authors: Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc/vlc.h>
33 #include <vlc_codec.h>
34 #include <vlc_vout.h>
35 #include <vlc_filter.h>
36
37 /* ffmpeg header */
38 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
39 #   include <libavcodec/avcodec.h>
40 #elif defined(HAVE_FFMPEG_AVCODEC_H)
41 #   include <ffmpeg/avcodec.h>
42 #else
43 #   include <avcodec.h>
44 #endif
45
46 #include "ffmpeg.h"
47
48 #if !defined(HAVE_LIBSWSCALE_SWSCALE_H)  && !defined(HAVE_FFMPEG_SWSCALE_H) && !defined(HAVE_LIBSWSCALE_TREE)
49 void E_(InitLibavcodec) ( vlc_object_t *p_object );
50 static int CheckInit( filter_t *p_filter );
51 static picture_t *Process( filter_t *p_filter, picture_t *p_pic );
52
53 /*****************************************************************************
54  * filter_sys_t : filter descriptor
55  *****************************************************************************/
56 struct filter_sys_t
57 {
58     bool b_resize;
59     bool b_convert;
60     bool b_resize_first;
61     bool b_enable_croppadd;
62
63     es_format_t fmt_in;
64     int i_src_ffmpeg_chroma;
65     es_format_t fmt_out;
66     int i_dst_ffmpeg_chroma;
67
68     AVPicture tmp_pic;
69
70     ImgReSampleContext *p_rsc;
71 };
72
73 /*****************************************************************************
74  * OpenFilterEx: common code to OpenFilter and OpenCropPadd
75  *****************************************************************************/
76 static int OpenFilterEx( vlc_object_t *p_this, bool b_enable_croppadd )
77 {
78     filter_t *p_filter = (filter_t*)p_this;
79     filter_sys_t *p_sys;
80     bool b_convert, b_resize;
81
82     /* Check if we can handle that formats */
83     if( E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma ) < 0 ||
84         E_(GetFfmpegChroma)( p_filter->fmt_out.video.i_chroma ) < 0 )
85     {
86         return VLC_EGENERIC;
87     }
88
89     b_resize =
90         ( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ) ||
91         ( p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height );
92
93     if ( b_enable_croppadd )
94     {
95         b_resize = b_resize ||
96            ( p_filter->fmt_in.video.i_visible_width != p_filter->fmt_in.video.i_width ) ||
97            ( p_filter->fmt_in.video.i_visible_height != p_filter->fmt_in.video.i_height ) ||
98            ( p_filter->fmt_in.video.i_x_offset != 0 ) ||
99            ( p_filter->fmt_in.video.i_y_offset != 0 ) ||
100            ( p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ) ||
101            ( p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ) ||
102            ( p_filter->fmt_out.video.i_x_offset != 0 ) ||
103            ( p_filter->fmt_out.video.i_y_offset != 0 );
104     }
105
106     b_convert =
107         ( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma );
108
109     if( !b_resize && !b_convert )
110     {
111         /* Nothing to do */
112         return VLC_EGENERIC;
113     }
114
115     /* Allocate the memory needed to store the decoder's structure */
116     if( ( p_filter->p_sys = p_sys =
117           (filter_sys_t *)malloc(sizeof(filter_sys_t)) ) == NULL )
118     {
119         msg_Err( p_filter, "out of memory" );
120         return VLC_EGENERIC;
121     }
122
123     /* Misc init */
124     p_sys->p_rsc = NULL;
125     p_sys->b_enable_croppadd = b_enable_croppadd;
126     p_sys->i_src_ffmpeg_chroma =
127         E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma );
128     p_sys->i_dst_ffmpeg_chroma =
129         E_(GetFfmpegChroma)( p_filter->fmt_out.video.i_chroma );
130     p_filter->pf_video_filter = Process;
131     es_format_Init( &p_sys->fmt_in, 0, 0 );
132     es_format_Init( &p_sys->fmt_out, 0, 0 );
133
134     /* Dummy alloc, will be reallocated in CheckInit */
135     avpicture_alloc( &p_sys->tmp_pic, p_sys->i_src_ffmpeg_chroma,
136                      p_filter->fmt_out.video.i_width,
137                      p_filter->fmt_out.video.i_height );
138
139     if( CheckInit( p_filter ) != VLC_SUCCESS )
140     {
141         if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
142         avpicture_free( &p_sys->tmp_pic );
143         free( p_sys );
144         return VLC_EGENERIC;
145     }
146
147     msg_Dbg( p_filter, "input: %ix%i %4.4s -> %ix%i %4.4s",
148              p_filter->fmt_in.video.i_width, p_filter->fmt_in.video.i_height,
149              (char *)&p_filter->fmt_in.video.i_chroma,
150              p_filter->fmt_out.video.i_width, p_filter->fmt_out.video.i_height,
151              (char *)&p_filter->fmt_out.video.i_chroma );
152
153     /* libavcodec needs to be initialized for some chroma conversions */
154     E_(InitLibavcodec)(p_this);
155
156     return VLC_SUCCESS;
157 }
158
159 /*****************************************************************************
160  * OpenFilter: probe the filter and return score
161  *****************************************************************************/
162 int E_(OpenFilter)( vlc_object_t *p_this )
163 {
164     return OpenFilterEx( p_this, false );
165 }
166
167 /*****************************************************************************
168  * OpenCropPadd: probe the filter and return score
169  *****************************************************************************/
170 int E_(OpenCropPadd)( vlc_object_t *p_this )
171 {
172     return OpenFilterEx( p_this, true );
173 }
174
175
176 /*****************************************************************************
177  * CloseFilter: clean up the filter
178  *****************************************************************************/
179 void E_(CloseFilter)( vlc_object_t *p_this )
180 {
181     filter_t *p_filter = (filter_t*)p_this;
182     filter_sys_t *p_sys = p_filter->p_sys;
183
184     if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
185     avpicture_free( &p_sys->tmp_pic );
186
187     free( p_sys );
188 }
189
190 /*****************************************************************************
191  * CheckInit: Initialise filter when necessary
192  *****************************************************************************/
193 static int CheckInit( filter_t *p_filter )
194 {
195     filter_sys_t *p_sys = p_filter->p_sys;
196     bool b_change;
197     int i_croptop=0;
198     int i_cropbottom=0;
199     int i_cropleft=0;
200     int i_cropright=0;
201     int i_paddtop=0;
202     int i_paddbottom=0;
203     int i_paddleft=0;
204     int i_paddright=0;
205
206     b_change = ( p_filter->fmt_in.video.i_width != p_sys->fmt_in.video.i_width ) ||
207         ( p_filter->fmt_in.video.i_height != p_sys->fmt_in.video.i_height ) ||
208         ( p_filter->fmt_out.video.i_width != p_sys->fmt_out.video.i_width ) ||
209         ( p_filter->fmt_out.video.i_height != p_sys->fmt_out.video.i_height );
210
211     if ( p_sys->b_enable_croppadd )
212     {
213         b_change = b_change ||
214             ( p_filter->fmt_in.video.i_y_offset != p_sys->fmt_in.video.i_y_offset ) ||
215             ( p_filter->fmt_in.video.i_x_offset != p_sys->fmt_in.video.i_x_offset ) ||
216             ( p_filter->fmt_in.video.i_visible_width != p_sys->fmt_in.video.i_visible_width ) ||
217             ( p_filter->fmt_in.video.i_visible_height != p_sys->fmt_in.video.i_visible_height ) ||
218             ( p_filter->fmt_out.video.i_y_offset != p_sys->fmt_out.video.i_y_offset ) ||
219             ( p_filter->fmt_out.video.i_x_offset != p_sys->fmt_out.video.i_x_offset ) ||
220             ( p_filter->fmt_out.video.i_visible_width != p_sys->fmt_out.video.i_visible_width ) ||
221             ( p_filter->fmt_out.video.i_visible_height != p_sys->fmt_out.video.i_visible_height );
222     }
223
224     if ( b_change )
225     {
226         if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
227
228         p_sys->p_rsc = NULL;
229         p_sys->b_convert =
230           ( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma );
231
232         p_sys->b_resize =
233           ( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ) ||
234           ( p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height );
235
236         p_sys->b_resize_first =
237           ( p_filter->fmt_in.video.i_width * p_filter->fmt_in.video.i_height ) >
238           ( p_filter->fmt_out.video.i_width * p_filter->fmt_out.video.i_height );
239
240         if( p_sys->b_resize &&
241             ( p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUV420P ) &&
242             ( p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUVJ420P ) &&
243             ( p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUV420P ) &&
244             ( p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUVJ420P ) )
245         {
246             msg_Err( p_filter, "img_resample_init only deals with I420" );
247             return VLC_EGENERIC;
248         }
249         else if( ( p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUV420P ) &&
250                  ( p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUVJ420P ) )
251         {
252             p_sys->b_resize_first = false;
253         }
254         else if( ( p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUV420P ) &&
255                  ( p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUVJ420P ) )
256         {
257             p_sys->b_resize_first = true;
258         }
259
260         if ( p_sys->b_enable_croppadd )
261         {
262             p_sys->b_resize = p_sys->b_resize ||
263                 ( p_filter->fmt_in.video.i_visible_width != p_filter->fmt_in.video.i_width ) ||
264                 ( p_filter->fmt_in.video.i_visible_height != p_filter->fmt_in.video.i_height ) ||
265                 ( p_filter->fmt_in.video.i_x_offset != 0 ) ||
266                 ( p_filter->fmt_in.video.i_y_offset != 0 ) ||
267                 ( p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ) ||
268                 ( p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ) ||
269                 ( p_filter->fmt_out.video.i_x_offset != 0 ) ||
270                 ( p_filter->fmt_out.video.i_y_offset != 0 );
271         }
272
273         if( p_sys->b_resize )
274         {
275             if ( p_sys->b_enable_croppadd )
276             {
277                 i_croptop = p_filter->fmt_in.video.i_y_offset;
278                 i_cropbottom = p_filter->fmt_in.video.i_height
279                                        - p_filter->fmt_in.video.i_visible_height
280                                        - p_filter->fmt_in.video.i_y_offset;
281                 i_cropleft = p_filter->fmt_in.video.i_x_offset;
282                 i_cropright = p_filter->fmt_in.video.i_width
283                                       - p_filter->fmt_in.video.i_visible_width
284                                       - p_filter->fmt_in.video.i_x_offset;
285
286
287                 i_paddtop = p_filter->fmt_out.video.i_y_offset;
288                 i_paddbottom = p_filter->fmt_out.video.i_height
289                                        - p_filter->fmt_out.video.i_visible_height
290                                        - p_filter->fmt_out.video.i_y_offset;
291                 i_paddleft = p_filter->fmt_out.video.i_x_offset;
292                 i_paddright = p_filter->fmt_out.video.i_width
293                                       - p_filter->fmt_out.video.i_visible_width
294                                       - p_filter->fmt_out.video.i_x_offset;
295             }
296
297             p_sys->p_rsc = img_resample_full_init(
298                                p_filter->fmt_out.video.i_width,
299                                p_filter->fmt_out.video.i_height,
300                                p_filter->fmt_in.video.i_width,
301                                p_filter->fmt_in.video.i_height,
302                                i_croptop,i_cropbottom,
303                                i_cropleft,i_cropright,
304                                i_paddtop,i_paddbottom,
305                                i_paddleft,i_paddright );
306
307             if( !p_sys->p_rsc )
308             {
309                 msg_Err( p_filter, "img_resample_init failed" );
310                 return VLC_EGENERIC;
311             }
312
313             msg_Dbg( p_filter, "input: %ix%i -> %ix%i",
314                 p_filter->fmt_out.video.i_width,
315                 p_filter->fmt_out.video.i_height,
316                 p_filter->fmt_in.video.i_width,
317                 p_filter->fmt_in.video.i_height);
318
319         }
320
321         avpicture_free( &p_sys->tmp_pic );
322
323         if( p_sys->b_resize_first )
324         {
325             /* Resizing then conversion */
326             avpicture_alloc( &p_sys->tmp_pic, p_sys->i_src_ffmpeg_chroma,
327                              p_filter->fmt_out.video.i_width,
328                              p_filter->fmt_out.video.i_height );
329         }
330         else
331         {
332             /* Conversion then resizing */
333             avpicture_alloc( &p_sys->tmp_pic, p_sys->i_dst_ffmpeg_chroma,
334                              p_filter->fmt_in.video.i_width,
335                              p_filter->fmt_in.video.i_height );
336         }
337
338         p_sys->fmt_in = p_filter->fmt_in;
339         p_sys->fmt_out = p_filter->fmt_out;
340     }
341
342     return VLC_SUCCESS;
343 }
344
345 /* fill padd code from ffmpeg */
346 static int padcolor[3] = { 16, 128, 128 };
347
348 /* Expects img to be yuv420 */
349 static void fill_pad_region( AVPicture* img, int height, int width,
350         int padtop, int padbottom, int padleft, int padright, int *color )
351 {
352     int i, y, shift;
353     uint8_t *optr;
354
355     for ( i = 0; i < 3; i++ )
356     {
357         shift = ( i == 0 ) ? 0 : 1;
358
359         if ( padtop || padleft )
360         {
361             memset( img->data[i], color[i], ( ( ( img->linesize[i] * padtop ) +
362                             padleft ) >> shift) );
363         }
364
365         if ( padleft || padright )
366         {
367             optr = img->data[i] + ( img->linesize[i] * ( padtop >> shift ) ) +
368                 ( img->linesize[i] - ( padright >> shift ) );
369
370             for ( y = 0; y < ( ( height - ( padtop + padbottom ) ) >> shift ); y++ )
371             {
372                 memset( optr, color[i], ( padleft + padright ) >> shift );
373                 optr += img->linesize[i];
374             }
375         }
376
377         if (padbottom)
378         {
379             optr = img->data[i] + ( img->linesize[i] * ( ( height - padbottom ) >> shift ) );
380             memset( optr, color[i], ( ( img->linesize[i] * padbottom ) >> shift ) );
381         }
382     }
383 }
384
385 /* Workaround, because old libavcodec doesnt know how to padd */
386 static void img_resample_padd( ImgReSampleContext *s, AVPicture *output,
387         const AVPicture *input, int padtop, int padleft )
388 {
389     AVPicture nopadd_pic = *output;
390
391     /* shift out top and left padding for old ffmpeg */
392     nopadd_pic.data[0] += ( nopadd_pic.linesize[0] * padtop + padleft );
393     nopadd_pic.data[1] += ( nopadd_pic.linesize[1] * padtop + padleft ) >> 1;
394     nopadd_pic.data[2] += ( nopadd_pic.linesize[2] * padtop + padleft ) >> 1;
395     img_resample( s, &nopadd_pic, input );
396 }
397
398
399 /*****************************************************************************
400  * Do the processing here
401  *****************************************************************************/
402 static picture_t *Process( filter_t *p_filter, picture_t *p_pic )
403 {
404     filter_sys_t *p_sys = p_filter->p_sys;
405     AVPicture src_pic, dest_pic;
406     AVPicture *p_src, *p_dst;
407     picture_t *p_pic_dst;
408     int i;
409
410     /* Check if format properties changed */
411     if( CheckInit( p_filter ) != VLC_SUCCESS ) return 0;
412
413     /* Request output picture */
414     p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
415     if( !p_pic_dst )
416     {
417         msg_Warn( p_filter, "can't get output picture" );
418         p_pic->pf_release( p_pic );
419         return NULL;
420     }
421
422     /* Prepare the AVPictures for the conversion */
423     for( i = 0; i < p_pic->i_planes; i++ )
424     {
425         src_pic.data[i] = p_pic->p[i].p_pixels;
426         src_pic.linesize[i] = p_pic->p[i].i_pitch;
427     }
428     for( i = 0; i < p_pic_dst->i_planes; i++ )
429     {
430         dest_pic.data[i] = p_pic_dst->p[i].p_pixels;
431         dest_pic.linesize[i] = p_pic_dst->p[i].i_pitch;
432     }
433
434     /* Special cases */
435     if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') ||
436         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','U','9') )
437     {
438         /* Invert U and V */
439         src_pic.data[1] = p_pic->p[2].p_pixels;
440         src_pic.data[2] = p_pic->p[1].p_pixels;
441     }
442     if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','1','2') ||
443         p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','U','9') )
444     {
445         /* Invert U and V */
446         dest_pic.data[1] = p_pic_dst->p[2].p_pixels;
447         dest_pic.data[2] = p_pic_dst->p[1].p_pixels;
448     }
449     if( p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 )
450         if( p_filter->fmt_in.video.i_bmask == 0x00ff0000 )
451             p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24;
452
453     p_src = &src_pic;
454
455     if( p_sys->b_resize && p_sys->p_rsc )
456     {
457         p_dst = &dest_pic;
458         if( p_sys->b_resize_first )
459         {
460             if( p_sys->b_convert ) p_dst = &p_sys->tmp_pic;
461
462             img_resample( p_sys->p_rsc, p_dst, p_src );
463
464             if (p_sys->b_enable_croppadd)
465             {
466                 if (p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
467                     p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
468                     p_filter->fmt_out.video.i_x_offset != 0 ||
469                     p_filter->fmt_out.video.i_y_offset != 0)
470                 {
471                     fill_pad_region(p_dst, p_filter->fmt_out.video.i_height,
472                                     p_filter->fmt_out.video.i_width,
473                                     p_filter->fmt_out.video.i_y_offset,
474                                     p_filter->fmt_out.video.i_height
475                                       - p_filter->fmt_out.video.i_visible_height
476                                       - p_filter->fmt_out.video.i_y_offset,
477                                     p_filter->fmt_out.video.i_x_offset,
478                                     p_filter->fmt_out.video.i_width
479                                       - p_filter->fmt_out.video.i_visible_width
480                                       - p_filter->fmt_out.video.i_x_offset,
481                                     padcolor);
482                 }
483             }
484
485             p_src = p_dst;
486         }
487     }
488
489     if( p_sys->b_convert )
490     {
491         video_format_t *p_fmt = &p_filter->fmt_out.video;
492         p_dst = &dest_pic;
493         if( p_sys->b_resize && !p_sys->b_resize_first )
494         {
495             p_dst = &p_sys->tmp_pic;
496             p_fmt = &p_filter->fmt_in.video;
497         }
498
499         img_convert( p_dst, p_sys->i_dst_ffmpeg_chroma,
500                      p_src, p_sys->i_src_ffmpeg_chroma,
501                      p_fmt->i_width, p_fmt->i_height );
502
503         p_src = p_dst;
504     }
505
506     if( p_sys->b_resize && !p_sys->b_resize_first && p_sys->p_rsc )
507     {
508         p_dst = &dest_pic;
509
510         img_resample( p_sys->p_rsc, p_dst, p_src );
511
512         if (p_sys->b_enable_croppadd)
513         {
514             if (p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
515                 p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
516                 p_filter->fmt_out.video.i_x_offset != 0 ||
517                 p_filter->fmt_out.video.i_y_offset != 0)
518             {
519                 fill_pad_region(p_dst, p_filter->fmt_out.video.i_height,
520                                 p_filter->fmt_out.video.i_width,
521                                 p_filter->fmt_out.video.i_y_offset,
522                                 p_filter->fmt_out.video.i_height
523                                   - p_filter->fmt_out.video.i_visible_height
524                                   - p_filter->fmt_out.video.i_y_offset,
525                                 p_filter->fmt_out.video.i_x_offset,
526                                 p_filter->fmt_out.video.i_width
527                                   - p_filter->fmt_out.video.i_visible_width
528                                   - p_filter->fmt_out.video.i_x_offset,
529                                 padcolor);
530             }
531         }
532     }
533
534     /* Special case for RV32 -> YUVA */
535     if( !p_sys->b_resize &&
536         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('R','V','3','2') &&
537         p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','V','A') )
538     {
539         uint8_t *p_src = p_pic->p[0].p_pixels;
540         int i_src_pitch = p_pic->p[0].i_pitch;
541         uint8_t *p_dst = p_pic_dst->p[3].p_pixels;
542         int i_dst_pitch = p_pic_dst->p[3].i_pitch;
543         uint32_t l,j;
544
545         for( l = 0; l < p_filter->fmt_out.video.i_height; l++ )
546         {
547             for( j = 0; j < p_filter->fmt_out.video.i_width; j++ )
548             {
549               p_dst[j] = p_src[j*4+3];
550             }
551             p_src += i_src_pitch;
552             p_dst += i_dst_pitch;
553         }
554     }
555     else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','V','A') )
556     {
557         /* Special case for YUVA */
558         memset( p_pic_dst->p[3].p_pixels, 0xFF,
559                 p_pic_dst->p[3].i_pitch * p_pic_dst->p[3].i_lines );
560     }
561
562     p_pic_dst->date = p_pic->date;
563     p_pic_dst->b_force = p_pic->b_force;
564     p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
565     p_pic_dst->b_progressive = p_pic->b_progressive;
566     p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
567
568     p_pic->pf_release( p_pic );
569     return p_pic_dst;
570 }
571 #endif /* ( (defined(HAVE_LIBSWSCALE_SWSCALE_H)  || defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) */