| | 1646 | |
|---|
| | 1647 | static filter_t *transcode_video_filter_new( sout_stream_t *p_stream, |
|---|
| | 1648 | es_format_t *p_fmt_in, |
|---|
| | 1649 | es_format_t *p_fmt_out, |
|---|
| | 1650 | config_chain_t *p_cfg, |
|---|
| | 1651 | const char *psz_name ) |
|---|
| | 1652 | { |
|---|
| | 1653 | sout_stream_sys_t *p_sys = p_stream->p_sys; |
|---|
| | 1654 | filter_t *p_filter; |
|---|
| | 1655 | int i; |
|---|
| | 1656 | |
|---|
| | 1657 | if( !p_stream || !p_fmt_in || !p_fmt_out ) return NULL; |
|---|
| | 1658 | |
|---|
| | 1659 | p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER ); |
|---|
| | 1660 | vlc_object_attach( p_filter, p_stream ); |
|---|
| | 1661 | |
|---|
| | 1662 | p_filter->pf_vout_buffer_new = video_new_buffer_filter; |
|---|
| | 1663 | p_filter->pf_vout_buffer_del = video_del_buffer_filter; |
|---|
| | 1664 | |
|---|
| | 1665 | es_format_Copy( &p_filter->fmt_in, p_fmt_in ); |
|---|
| | 1666 | es_format_Copy( &p_filter->fmt_out, p_fmt_out ); |
|---|
| | 1667 | p_filter->p_cfg = p_cfg; |
|---|
| | 1668 | |
|---|
| | 1669 | p_filter->p_module = module_Need( p_filter, "video filter2", |
|---|
| | 1670 | psz_name, VLC_TRUE ); |
|---|
| | 1671 | if( !p_filter->p_module ) |
|---|
| | 1672 | { |
|---|
| | 1673 | msg_Dbg( p_stream, "no video filter found" ); |
|---|
| | 1674 | vlc_object_detach( p_filter ); |
|---|
| | 1675 | vlc_object_release( p_filter ); |
|---|
| | 1676 | return NULL; |
|---|
| | 1677 | } |
|---|
| | 1678 | |
|---|
| | 1679 | p_filter->p_owner = malloc( sizeof(filter_owner_sys_t) ); |
|---|
| | 1680 | if( !p_filter->p_owner ) |
|---|
| | 1681 | { |
|---|
| | 1682 | module_Unneed( p_filter,p_filter->p_module ); |
|---|
| | 1683 | vlc_object_detach( p_filter ); |
|---|
| | 1684 | vlc_object_release( p_filter ); |
|---|
| | 1685 | return NULL; |
|---|
| | 1686 | } |
|---|
| | 1687 | |
|---|
| | 1688 | for( i = 0; i < PICTURE_RING_SIZE; i++ ) |
|---|
| | 1689 | p_filter->p_owner->pp_pics[i] = 0; |
|---|
| | 1690 | p_filter->p_owner->p_sys = p_sys; |
|---|
| | 1691 | |
|---|
| | 1692 | return p_filter; |
|---|
| | 1693 | } |
|---|
| | 1694 | |
|---|
| | 1695 | static void transcode_video_filter_close( sout_stream_t *p_stream, |
|---|
| | 1696 | filter_t *p_filter ) |
|---|
| | 1697 | { |
|---|
| | 1698 | int j; |
|---|
| | 1699 | |
|---|
| | 1700 | if( !p_stream || !p_filter ) return; |
|---|
| | 1701 | |
|---|
| | 1702 | vlc_object_detach( p_filter ); |
|---|
| | 1703 | if( p_filter->p_module ) |
|---|
| | 1704 | module_Unneed( p_filter, p_filter->p_module ); |
|---|
| | 1705 | |
|---|
| | 1706 | /* Clean-up pictures ring buffer */ |
|---|
| | 1707 | for( j = 0; j < PICTURE_RING_SIZE; j++ ) |
|---|
| | 1708 | { |
|---|
| | 1709 | if( p_filter->p_owner->pp_pics[j] ) |
|---|
| | 1710 | video_del_buffer( VLC_OBJECT(p_filter), |
|---|
| | 1711 | p_filter->p_owner->pp_pics[j] ); |
|---|
| | 1712 | } |
|---|
| | 1713 | free( p_filter->p_owner ); |
|---|
| | 1714 | vlc_object_release( p_filter ); |
|---|
| | 1715 | p_filter = NULL; |
|---|
| | 1716 | } |
|---|
| | 1717 | |
|---|
| 2087 | | vlc_object_detach( id->pp_filter[i] ); |
|---|
| 2088 | | if( id->pp_filter[i]->p_module ) |
|---|
| 2089 | | module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module ); |
|---|
| 2090 | | |
|---|
| 2091 | | /* Clean-up pictures ring buffer */ |
|---|
| 2092 | | for( j = 0; j < PICTURE_RING_SIZE; j++ ) |
|---|
| 2093 | | { |
|---|
| 2094 | | if( id->pp_filter[i]->p_owner->pp_pics[j] ) |
|---|
| 2095 | | video_del_buffer( VLC_OBJECT(id->pp_filter[i]), |
|---|
| 2096 | | id->pp_filter[i]->p_owner->pp_pics[j] ); |
|---|
| 2097 | | } |
|---|
| 2098 | | free( id->pp_filter[i]->p_owner ); |
|---|
| 2099 | | vlc_object_release( id->pp_filter[i] ); |
|---|
| | 2159 | transcode_video_filter_close( p_stream, id->pp_filter[i] ); |
|---|
| 2105 | | vlc_object_detach( id->pp_ufilter[i] ); |
|---|
| 2106 | | if( id->pp_ufilter[i]->p_module ) |
|---|
| 2107 | | module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module ); |
|---|
| 2108 | | |
|---|
| 2109 | | /* Clean-up pictures ring buffer */ |
|---|
| 2110 | | for( j = 0; j < PICTURE_RING_SIZE; j++ ) |
|---|
| 2111 | | { |
|---|
| 2112 | | if( id->pp_ufilter[i]->p_owner->pp_pics[j] ) |
|---|
| 2113 | | video_del_buffer( VLC_OBJECT(id->pp_ufilter[i]), |
|---|
| 2114 | | id->pp_ufilter[i]->p_owner->pp_pics[j] ); |
|---|
| 2115 | | } |
|---|
| 2116 | | free( id->pp_ufilter[i]->p_owner ); |
|---|
| 2117 | | vlc_object_release( id->pp_ufilter[i] ); |
|---|
| | 2166 | transcode_video_filter_close( p_stream, id->pp_ufilter[i] ); |
|---|
| 2202 | | vlc_object_create( p_stream, VLC_OBJECT_FILTER ); |
|---|
| 2203 | | vlc_object_attach( id->pp_filter[id->i_filter], p_stream ); |
|---|
| 2204 | | |
|---|
| 2205 | | id->pp_filter[id->i_filter]->pf_vout_buffer_new = |
|---|
| 2206 | | video_new_buffer_filter; |
|---|
| 2207 | | id->pp_filter[id->i_filter]->pf_vout_buffer_del = |
|---|
| 2208 | | video_del_buffer_filter; |
|---|
| 2209 | | |
|---|
| 2210 | | id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out; |
|---|
| 2211 | | id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out; |
|---|
| 2212 | | id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg; |
|---|
| 2213 | | id->pp_filter[id->i_filter]->p_module = |
|---|
| 2214 | | module_Need( id->pp_filter[id->i_filter], |
|---|
| 2215 | | "video filter2", p_sys->psz_deinterlace, |
|---|
| 2216 | | VLC_TRUE ); |
|---|
| 2217 | | if( id->pp_filter[id->i_filter]->p_module ) |
|---|
| | 2252 | transcode_video_filter_new( p_stream, |
|---|
| | 2253 | &id->p_decoder->fmt_out, &id->p_encoder->fmt_in, |
|---|
| | 2254 | p_sys->p_deinterlace_cfg, |
|---|
| | 2255 | p_sys->psz_deinterlace ); |
|---|
| | 2256 | |
|---|
| | 2257 | if( id->pp_filter[id->i_filter] ) |
|---|
| | 2258 | id->i_filter++; |
|---|
| | 2259 | } |
|---|
| | 2260 | |
|---|
| | 2261 | #if (defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) || defined(HAVE_LIBSWSCALE_SWSCALE_H) |
|---|
| | 2262 | if( ( id->p_decoder->fmt_out.video.i_chroma != |
|---|
| | 2263 | id->p_encoder->fmt_in.video.i_chroma ) || |
|---|
| | 2264 | ( id->p_decoder->fmt_out.video.i_width != |
|---|
| | 2265 | id->p_encoder->fmt_out.video.i_width ) || |
|---|
| | 2266 | ( id->p_decoder->fmt_out.video.i_height != |
|---|
| | 2267 | id->p_encoder->fmt_out.video.i_height ) ) |
|---|
| | 2268 | { |
|---|
| | 2269 | id->pp_filter[id->i_filter] = |
|---|
| | 2270 | transcode_video_filter_new( p_stream, |
|---|
| | 2271 | &id->p_decoder->fmt_out, &id->p_encoder->fmt_in, |
|---|
| | 2272 | NULL, "scale" ); |
|---|
| | 2273 | if( !id->pp_filter[id->i_filter] ) |
|---|
| 2219 | | id->pp_filter[id->i_filter]->p_owner = |
|---|
| 2220 | | malloc( sizeof(filter_owner_sys_t) ); |
|---|
| 2221 | | for( i = 0; i < PICTURE_RING_SIZE; i++ ) |
|---|
| 2222 | | id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0; |
|---|
| 2223 | | id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys; |
|---|
| | 2275 | p_pic->pf_release( p_pic ); |
|---|
| | 2276 | transcode_video_close( p_stream, id ); |
|---|
| | 2277 | id->b_transcode = VLC_FALSE; |
|---|
| | 2278 | return VLC_EGENERIC; |
|---|
| | 2279 | } |
|---|
| | 2280 | id->i_filter++; |
|---|
| | 2281 | } |
|---|
| | 2282 | #if 0 /* FIXME: */ |
|---|
| | 2283 | /* we don't do chroma conversion or scaling in croppad */ |
|---|
| | 2284 | // es_format_t fmt_in, fmt_out; |
|---|
| | 2285 | // es_format_Copy( &fmt_out, &id->p_encoder->fmt_in ); |
|---|
| | 2286 | // es_format_Copy( &fmt_in, &id->p_encoder->fmt_in ); |
|---|
| | 2287 | |
|---|
| | 2288 | if( ( id->p_decoder->fmt_out.video.i_chroma == |
|---|
| | 2289 | id->p_encoder->fmt_in.video.i_chroma ) && |
|---|
| | 2290 | |
|---|
| | 2291 | ( ( (int)id->p_decoder->fmt_out.video.i_width != |
|---|
| | 2292 | p_sys->i_crop_width ) || |
|---|
| | 2293 | ( p_sys->i_crop_width != p_sys->i_nopadd_width ) || |
|---|
| | 2294 | ( p_sys->i_nopadd_width != |
|---|
| | 2295 | (int)id->p_encoder->fmt_out.video.i_width ) || |
|---|
| | 2296 | |
|---|
| | 2297 | ( (int)id->p_decoder->fmt_out.video.i_height != |
|---|
| | 2298 | p_sys->i_crop_height ) || |
|---|
| | 2299 | ( p_sys->i_crop_height != p_sys->i_nopadd_height ) || |
|---|
| | 2300 | ( p_sys->i_nopadd_height != |
|---|
| | 2301 | (int)id->p_encoder->fmt_out.video.i_height ) ) ) |
|---|
| | 2302 | { |
|---|
| | 2303 | id->pp_filter[id->i_filter] = |
|---|
| | 2304 | transcode_video_filter_new( p_stream, |
|---|
| | 2305 | &id->p_decoder->fmt_out, &id->p_encoder->fmt_in, |
|---|
| | 2306 | NULL, "croppadd" ); |
|---|
| | 2307 | if( id->pp_filter[id->i_filter] ) |
|---|
| | 2308 | { |
|---|
| | 2309 | /* Set crop and padding information */ |
|---|
| | 2310 | id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset; |
|---|
| | 2311 | id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset; |
|---|
| | 2312 | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width; |
|---|
| | 2313 | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height; |
|---|
| | 2314 | |
|---|
| | 2315 | id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset; |
|---|
| | 2316 | id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset; |
|---|
| | 2317 | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width; |
|---|
| | 2318 | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height; |
|---|
| 2248 | | vlc_object_create( p_stream, VLC_OBJECT_FILTER ); |
|---|
| 2249 | | vlc_object_attach( id->pp_filter[id->i_filter], p_stream ); |
|---|
| 2250 | | |
|---|
| 2251 | | id->pp_filter[id->i_filter]->pf_vout_buffer_new = |
|---|
| 2252 | | video_new_buffer_filter; |
|---|
| 2253 | | id->pp_filter[id->i_filter]->pf_vout_buffer_del = |
|---|
| 2254 | | video_del_buffer_filter; |
|---|
| 2255 | | |
|---|
| 2256 | | id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out; |
|---|
| 2257 | | id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in; |
|---|
| 2258 | | id->pp_filter[id->i_filter]->p_cfg = NULL; |
|---|
| 2259 | | |
|---|
| 2260 | | id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset; |
|---|
| 2261 | | id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset; |
|---|
| 2262 | | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width; |
|---|
| 2263 | | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height; |
|---|
| 2264 | | |
|---|
| 2265 | | id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset; |
|---|
| 2266 | | id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset; |
|---|
| 2267 | | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width; |
|---|
| 2268 | | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height; |
|---|
| 2269 | | |
|---|
| 2270 | | id->pp_filter[id->i_filter]->p_module = |
|---|
| 2271 | | module_Need( id->pp_filter[id->i_filter], |
|---|
| 2272 | | #if ( (defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) ) |
|---|
| 2273 | | "video filter2", "scale", VLC_TRUE ); |
|---|
| 2274 | | #else |
|---|
| 2275 | | "crop padd", 0, 0 ); |
|---|
| 2276 | | #endif |
|---|
| 2277 | | if( id->pp_filter[id->i_filter]->p_module ) |
|---|
| | 2338 | transcode_video_filter_new( p_stream, |
|---|
| | 2339 | &id->p_decoder->fmt_in, &id->p_encoder->fmt_in, |
|---|
| | 2340 | NULL, "crop padd" ); |
|---|
| | 2341 | if( !id->pp_filter[id->i_filter] ) |
|---|
| 2279 | | id->pp_filter[id->i_filter]->p_owner = |
|---|
| 2280 | | malloc( sizeof(filter_owner_sys_t) ); |
|---|
| 2281 | | for( i = 0; i < PICTURE_RING_SIZE; i++ ) |
|---|
| 2282 | | id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0; |
|---|
| 2283 | | id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys; |
|---|
| 2284 | | |
|---|
| 2285 | | id->i_filter++; |
|---|
| 2286 | | } |
|---|
| 2287 | | else |
|---|
| 2288 | | { |
|---|
| 2289 | | msg_Dbg( p_stream, "no video filter found" ); |
|---|
| 2290 | | vlc_object_detach( id->pp_filter[id->i_filter] ); |
|---|
| 2291 | | vlc_object_release( id->pp_filter[id->i_filter] ); |
|---|
| 2292 | | |
|---|
| | 2348 | |
|---|
| | 2349 | /* Set crop and padding information */ |
|---|
| | 2350 | id->pp_filter[id->i_filter]->fmt_in.video.i_x_offset = p_sys->i_src_x_offset; |
|---|
| | 2351 | id->pp_filter[id->i_filter]->fmt_in.video.i_y_offset = p_sys->i_src_y_offset; |
|---|
| | 2352 | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_width = p_sys->i_crop_width; |
|---|
| | 2353 | id->pp_filter[id->i_filter]->fmt_in.video.i_visible_height = p_sys->i_crop_height; |
|---|
| | 2354 | |
|---|
| | 2355 | id->pp_filter[id->i_filter]->fmt_out.video.i_x_offset = p_sys->i_dst_x_offset; |
|---|
| | 2356 | id->pp_filter[id->i_filter]->fmt_out.video.i_y_offset = p_sys->i_dst_y_offset; |
|---|
| | 2357 | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_width = p_sys->i_nopadd_width; |
|---|
| | 2358 | id->pp_filter[id->i_filter]->fmt_out.video.i_visible_height = p_sys->i_nopadd_height; |
|---|
| | 2359 | |
|---|
| | 2360 | id->i_filter++; |
|---|
| 2303 | | vlc_object_create( p_stream, VLC_OBJECT_FILTER ); |
|---|
| 2304 | | vlc_object_attach( id->pp_ufilter[id->i_ufilter], p_stream ); |
|---|
| 2305 | | |
|---|
| 2306 | | id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_new = |
|---|
| 2307 | | video_new_buffer_filter; |
|---|
| 2308 | | id->pp_ufilter[id->i_ufilter]->pf_vout_buffer_del = |
|---|
| 2309 | | video_del_buffer_filter; |
|---|
| 2310 | | |
|---|
| 2311 | | id->pp_ufilter[id->i_ufilter]->fmt_in = id->p_encoder->fmt_in; |
|---|
| 2312 | | id->pp_ufilter[id->i_ufilter]->fmt_out = id->p_encoder->fmt_in; |
|---|
| 2313 | | id->pp_ufilter[id->i_ufilter]->p_cfg = p_sys->p_vfilters_cfg[i]; |
|---|
| 2314 | | id->pp_ufilter[id->i_ufilter]->p_module = |
|---|
| 2315 | | module_Need( id->pp_ufilter[id->i_ufilter], |
|---|
| 2316 | | "video filter2", p_sys->psz_vfilters[i], VLC_TRUE ); |
|---|
| 2317 | | if( id->pp_ufilter[id->i_ufilter]->p_module ) |
|---|
| 2318 | | { |
|---|
| 2319 | | id->pp_ufilter[id->i_ufilter]->p_owner = |
|---|
| 2320 | | malloc( sizeof(filter_owner_sys_t) ); |
|---|
| 2321 | | for( i = 0; i < PICTURE_RING_SIZE; i++ ) |
|---|
| 2322 | | id->pp_ufilter[id->i_ufilter]->p_owner->pp_pics[i] = 0; |
|---|
| 2323 | | id->pp_ufilter[id->i_ufilter]->p_owner->p_sys = p_sys; |
|---|
| | 2366 | transcode_video_filter_new( p_stream, |
|---|
| | 2367 | &id->p_decoder->fmt_out, &id->p_encoder->fmt_in, |
|---|
| | 2368 | p_sys->p_vfilters_cfg[i], p_sys->psz_vfilters[i] ); |
|---|
| | 2369 | if( id->pp_ufilter[id->i_filter] ) |
|---|