11#include "video_converter.h"
2+ #include "utils.h"
23
3- int video_converter_convert (AVFrame * src_frame , AVFrame * * dst_frame ,
4- enum AVPixelFormat out_format ) {
5- int ret ;
4+ static inline unsigned int video_converter_resolution_changed (struct VideoConverter * converter , AVFrame * frame ) {
5+ return converter -> in_format != frame -> format ||
6+ converter -> in_width != frame -> width ||
7+ converter -> in_height != frame -> height ;
8+ }
69
7- * dst_frame = av_frame_alloc ();
8- if (!* dst_frame ) {
9- return -1 ;
10+ struct VideoConverter * video_converter_alloc () {
11+ struct VideoConverter * converter =
12+ (struct VideoConverter * )XAV_ALLOC (sizeof (struct VideoConverter ));
13+ if (converter ) {
14+ converter -> sws_ctx = NULL ;
15+ converter -> dst_frame = av_frame_alloc ();
1016 }
17+ return converter ;
18+ }
19+
20+ int video_converter_init (struct VideoConverter * converter , int in_width , int in_height ,
21+ enum AVPixelFormat in_format , enum AVPixelFormat out_format ) {
22+ converter -> in_width = in_width ;
23+ converter -> in_height = in_height ;
24+ converter -> in_format = in_format ;
25+ converter -> out_format = out_format ;
26+
27+ av_frame_unref (converter -> dst_frame );
1128
12- (* dst_frame )-> width = src_frame -> width ;
13- (* dst_frame )-> height = src_frame -> height ;
14- (* dst_frame )-> format = out_format ;
15- (* dst_frame )-> pts = src_frame -> pts ;
29+ converter -> dst_frame -> width = in_width ;
30+ converter -> dst_frame -> height = in_height ;
31+ converter -> dst_frame -> format = out_format ;
1632
17- ret = av_frame_get_buffer (* dst_frame , 0 );
18- if (ret < 0 ) {
33+ int ret = av_frame_get_buffer (converter -> dst_frame , 0 );
34+ if (ret < 0 )
1935 return ret ;
36+
37+ converter -> sws_ctx = sws_getContext (in_width , in_height , in_format , in_width , in_height , out_format ,
38+ SWS_BILINEAR , NULL , NULL , NULL );
39+
40+ if (!converter -> sws_ctx ) {
41+ XAV_LOG_DEBUG ("Couldn't get sws context" );
42+ return -1 ;
2043 }
2144
22- struct SwsContext * sws_ctx =
23- sws_getContext (src_frame -> width , src_frame -> height , src_frame -> format , src_frame -> width ,
24- src_frame -> height , out_format , SWS_BILINEAR , NULL , NULL , NULL );
45+ return 0 ;
46+ }
2547
26- if (ret < 0 ) {
27- return ret ;
48+ int video_converter_convert (struct VideoConverter * converter , AVFrame * src_frame ) {
49+ int ret ;
50+
51+ if (video_converter_resolution_changed (converter , src_frame )) {
52+ XAV_LOG_DEBUG ("Frame resolution changed" );
53+ sws_freeContext (converter -> sws_ctx );
54+ ret = video_converter_init (converter , src_frame -> width , src_frame -> height ,
55+ src_frame -> format , converter -> out_format );
56+ if (ret < 0 ) {
57+ return ret ;
58+ }
2859 }
2960
61+ converter -> dst_frame -> pts = src_frame -> pts ;
62+
3063 // is this (const uint8_t * const*) cast really correct?
31- ret = sws_scale (sws_ctx , (const uint8_t * const * )src_frame -> data , src_frame -> linesize , 0 ,
32- src_frame -> height , (* dst_frame )-> data , (* dst_frame )-> linesize );
64+ return sws_scale (converter -> sws_ctx , (const uint8_t * const * )src_frame -> data , src_frame -> linesize , 0 ,
65+ src_frame -> height , converter -> dst_frame -> data , converter -> dst_frame -> linesize );
66+ }
3367
34- if (ret < 0 ) {
35- av_frame_free (dst_frame );
36- sws_freeContext (sws_ctx );
37- return ret ;
38- }
68+ void video_converter_free (struct VideoConverter * * converter ) {
69+ struct VideoConverter * vc = * converter ;
70+ if (vc != NULL ) {
71+ if (vc -> sws_ctx != NULL ) {
72+ sws_freeContext ((* converter )-> sws_ctx );
73+ }
3974
40- sws_freeContext (sws_ctx );
75+ if (vc -> dst_frame != NULL ) {
76+ av_frame_free (& (* converter )-> dst_frame );
77+ }
4178
42- return ret ;
79+ XAV_FREE (vc );
80+ * converter = NULL ;
81+ }
4382}
0 commit comments