2121
2222#include "libavutil/avassert.h"
2323#include "avcodec.h"
24+ #include "bsf.h"
2425#include "get_bits.h"
2526
2627#define MAX_CACHE 8
@@ -50,20 +51,20 @@ static void stats(const struct CachedBuf *in, int n_in,
5051 * _sum = sum ;
5152}
5253
53- static int merge_superframe (const struct CachedBuf * in , int n_in ,
54- uint8_t * * poutbuf , int * poutbuf_size )
54+ static int merge_superframe (const struct CachedBuf * in , int n_in , AVPacket * out )
5555{
5656 unsigned max , sum , mag , marker , n , sz ;
5757 uint8_t * ptr ;
58+ int res ;
5859
5960 stats (in , n_in , & max , & sum );
6061 mag = av_log2 (max ) >> 3 ;
6162 marker = 0xC0 + (mag << 3 ) + (n_in - 1 );
62- sz = * poutbuf_size = sum + 2 + (mag + 1 ) * n_in ;
63- ptr = * poutbuf = av_malloc ( sz );
64- if (! ptr )
65- return AVERROR ( ENOMEM ) ;
66-
63+ sz = sum + 2 + (mag + 1 ) * n_in ;
64+ res = av_new_packet ( out , sz );
65+ if (res < 0 )
66+ return res ;
67+ ptr = out -> data ;
6768 for (n = 0 ; n < n_in ; n ++ ) {
6869 memcpy (ptr , in [n ].data , in [n ].size );
6970 ptr += in [n ].size ;
@@ -92,31 +93,32 @@ static int merge_superframe(const struct CachedBuf *in, int n_in,
9293 break ;
9394 }
9495 * ptr ++ = marker ;
95- av_assert0 (ptr == & ( * poutbuf )[ * poutbuf_size ]);
96+ av_assert0 (ptr == & out -> data [ out -> size ]);
9697
9798 return 0 ;
9899}
99100
100- static int vp9_superframe_filter (AVBitStreamFilterContext * bsfc ,
101- AVCodecContext * avctx , const char * args ,
102- uint8_t * * poutbuf , int * poutbuf_size ,
103- const uint8_t * buf , int buf_size ,
104- int keyframe )
101+ static int vp9_superframe_filter (AVBSFContext * ctx , AVPacket * out )
105102{
106103 GetBitContext gb ;
107- VP9BSFContext * ctx = bsfc -> priv_data ;
104+ VP9BSFContext * s = ctx -> priv_data ;
105+ AVPacket * in ;
108106 int res , invisible , profile , marker , uses_superframe_syntax = 0 , n ;
109107
110- marker = buf [buf_size - 1 ];
108+ res = ff_bsf_get_packet (ctx , & in );
109+ if (res < 0 )
110+ return res ;
111+
112+ marker = in -> data [in -> size - 1 ];
111113 if ((marker & 0xe0 ) == 0xc0 ) {
112114 int nbytes = 1 + ((marker >> 3 ) & 0x3 );
113115 int n_frames = 1 + (marker & 0x7 ), idx_sz = 2 + n_frames * nbytes ;
114116
115- uses_superframe_syntax = buf_size >= idx_sz && buf [ buf_size - idx_sz ] == marker ;
117+ uses_superframe_syntax = in -> size >= idx_sz && in -> data [ in -> size - idx_sz ] == marker ;
116118 }
117119
118- if ((res = init_get_bits8 (& gb , buf , buf_size )) < 0 )
119- return res ;
120+ if ((res = init_get_bits8 (& gb , in -> data , in -> size )) < 0 )
121+ goto done ;
120122
121123 get_bits (& gb , 2 ); // frame marker
122124 profile = get_bits1 (& gb );
@@ -130,60 +132,69 @@ static int vp9_superframe_filter(AVBitStreamFilterContext *bsfc,
130132 invisible = !get_bits1 (& gb );
131133 }
132134
133- if (uses_superframe_syntax && ctx -> n_cache > 0 ) {
134- av_log (avctx , AV_LOG_ERROR ,
135+ if (uses_superframe_syntax && s -> n_cache > 0 ) {
136+ av_log (ctx , AV_LOG_ERROR ,
135137 "Mixing of superframe syntax and naked VP9 frames not supported" );
136- return AVERROR_INVALIDDATA ;
137- } else if ((!invisible || uses_superframe_syntax ) && !ctx -> n_cache ) {
138+ res = AVERROR_INVALIDDATA ;
139+ goto done ;
140+ } else if ((!invisible || uses_superframe_syntax ) && !s -> n_cache ) {
138141 // passthrough
139- * poutbuf = (uint8_t * ) buf ;
140- * poutbuf_size = buf_size ;
141- return 0 ;
142- } else if (ctx -> n_cache + 1 >= MAX_CACHE ) {
143- av_log (avctx , AV_LOG_ERROR ,
142+ av_packet_move_ref (out , in );
143+ goto done ;
144+ } else if (s -> n_cache + 1 >= MAX_CACHE ) {
145+ av_log (ctx , AV_LOG_ERROR ,
144146 "Too many invisible frames" );
145- return AVERROR_INVALIDDATA ;
147+ res = AVERROR_INVALIDDATA ;
148+ goto done ;
146149 }
147150
148- ctx -> cache [ctx -> n_cache ].size = buf_size ;
151+ s -> cache [s -> n_cache ].size = in -> size ;
149152 if (invisible && !uses_superframe_syntax ) {
150- ctx -> cache [ctx -> n_cache ].data = av_malloc (buf_size );
151- if (!ctx -> cache [ctx -> n_cache ].data )
152- return AVERROR (ENOMEM );
153- memcpy ( ctx -> cache [ ctx -> n_cache ++ ]. data , buf , buf_size ) ;
154- * poutbuf = NULL ;
155- * poutbuf_size = 0 ;
156- return 0 ;
153+ s -> cache [s -> n_cache ].data = av_malloc (in -> size );
154+ if (!s -> cache [s -> n_cache ].data ) {
155+ res = AVERROR (ENOMEM );
156+ goto done ;
157+ }
158+ memcpy ( s -> cache [ s -> n_cache ++ ]. data , in -> data , in -> size ) ;
159+ goto done ;
157160 }
158- av_assert0 (ctx -> n_cache > 0 );
161+ av_assert0 (s -> n_cache > 0 );
159162
160- ctx -> cache [ctx -> n_cache ].data = ( uint8_t * ) buf ;
163+ s -> cache [s -> n_cache ].data = in -> data ;
161164
162165 // build superframe
163- if ((res = merge_superframe (ctx -> cache , ctx -> n_cache + 1 ,
164- poutbuf , poutbuf_size )) < 0 )
165- return res ;
166-
167- for (n = 0 ; n < ctx -> n_cache ; n ++ )
168- av_freep (& ctx -> cache [n ].data );
169- ctx -> n_cache = 0 ;
170-
171- return 0 ;
166+ if ((res = merge_superframe (s -> cache , s -> n_cache + 1 , out )) < 0 )
167+ goto done ;
168+
169+ for (n = 0 ; n < s -> n_cache ; n ++ )
170+ av_freep (& s -> cache [n ].data );
171+ s -> n_cache = 0 ;
172+
173+ done :
174+ if (res < 0 )
175+ av_packet_unref (out );
176+ av_packet_free (& in );
177+ return res ;
172178}
173179
174- static void vp9_superframe_close (AVBitStreamFilterContext * bsfc )
180+ static void vp9_superframe_close (AVBSFContext * ctx )
175181{
176- VP9BSFContext * ctx = bsfc -> priv_data ;
182+ VP9BSFContext * s = ctx -> priv_data ;
177183 int n ;
178184
179185 // free cached data
180- for (n = 0 ; n < ctx -> n_cache ; n ++ )
181- av_freep (& ctx -> cache [n ].data );
186+ for (n = 0 ; n < s -> n_cache ; n ++ )
187+ av_freep (& s -> cache [n ].data );
182188}
183189
184- AVBitStreamFilter ff_vp9_superframe_bsf = {
190+ static const enum AVCodecID codec_ids [] = {
191+ AV_CODEC_ID_VP9 , AV_CODEC_ID_NONE ,
192+ };
193+
194+ const AVBitStreamFilter ff_vp9_superframe_bsf = {
185195 .name = "vp9_superframe" ,
186196 .priv_data_size = sizeof (VP9BSFContext ),
187197 .filter = vp9_superframe_filter ,
188198 .close = vp9_superframe_close ,
199+ .codec_ids = codec_ids ,
189200};
0 commit comments