4444/** decoder context */
4545typedef struct EightSvxContext {
4646 AVFrame frame ;
47+ uint8_t fib_acc [2 ];
4748 const int8_t * table ;
4849
49- /* buffer used to store the whole audio decoded/interleaved chunk,
50- * which is sent with the first packet */
51- uint8_t * samples ;
52- int64_t samples_size ;
53- int samples_idx ;
50+ /* buffer used to store the whole first packet.
51+ data is only sent as one large packet */
52+ uint8_t * data [ 2 ] ;
53+ int data_size ;
54+ int data_idx ;
5455} EightSvxContext ;
5556
5657static const int8_t fibonacci [16 ] = { -34 , -21 , -13 , -8 , -5 , -3 , -2 , -1 , 0 , 1 , 2 , 3 , 5 , 8 , 13 , 21 };
@@ -60,16 +61,15 @@ static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1, 0,
6061
6162/**
6263 * Delta decode the compressed values in src, and put the resulting
63- * decoded n samples in dst.
64+ * decoded samples in dst.
6465 *
65- * @param val starting value assumed by the delta sequence
66+ * @param[in,out] state starting value. it is saved for use in the next call.
6667 * @param table delta sequence table
67- * @return size in bytes of the decoded data, must be src_size*2
6868 */
69- static int delta_decode (uint8_t * dst , const uint8_t * src , int src_size ,
70- unsigned val , const int8_t * table )
69+ static void delta_decode (uint8_t * dst , const uint8_t * src , int src_size ,
70+ uint8_t * state , const int8_t * table )
7171{
72- uint8_t * dst0 = dst ;
72+ uint8_t val = * state ;
7373
7474 while (src_size -- ) {
7575 uint8_t d = * src ++ ;
@@ -79,7 +79,7 @@ static int delta_decode(uint8_t *dst, const uint8_t *src, int src_size,
7979 * dst ++ = val ;
8080 }
8181
82- return dst - dst0 ;
82+ * state = val ;
8383}
8484
8585static void raw_decode (uint8_t * dst , const int8_t * src , int src_size )
@@ -93,72 +93,79 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
9393 int * got_frame_ptr , AVPacket * avpkt )
9494{
9595 EightSvxContext * esc = avctx -> priv_data ;
96- int n , out_data_size ;
96+ int buf_size ;
9797 int ch , ret ;
98+ int is_compr = (avctx -> codec_id != AV_CODEC_ID_PCM_S8_PLANAR );
9899 uint8_t * src ;
100+ int hdr_size = is_compr ? 2 : 0 ;
99101
100102 /* decode and interleave the first packet */
101- if (!esc -> samples && avpkt ) {
102- int packet_size = avpkt -> size ;
103+ if (!esc -> data [ 0 ] && avpkt ) {
104+ int chan_size = avpkt -> size / avctx -> channels - hdr_size ;
103105
104- if (packet_size % avctx -> channels ) {
106+ if (avpkt -> size % avctx -> channels ) {
105107 av_log (avctx , AV_LOG_WARNING , "Packet with odd size, ignoring last byte\n" );
106- if (packet_size < avctx -> channels )
107- return packet_size ;
108- packet_size -= packet_size % avctx -> channels ;
109108 }
110- esc -> samples_size = !esc -> table ?
111- packet_size : avctx -> channels + (packet_size - avctx -> channels ) * 2 ;
112- if (!(esc -> samples = av_malloc (esc -> samples_size )))
113- return AVERROR (ENOMEM );
114-
115- /* decompress */
116- if (esc -> table ) {
117- const uint8_t * buf = avpkt -> data ;
118- uint8_t * dst ;
119- int buf_size = avpkt -> size ;
120- int i , n = esc -> samples_size ;
109+ if (avpkt -> size < (hdr_size + 1 ) * avctx -> channels ) {
110+ av_log (avctx , AV_LOG_ERROR , "packet size is too small\n" );
111+ return AVERROR (EINVAL );
112+ }
121113
122- if (buf_size < 2 ) {
123- av_log (avctx , AV_LOG_ERROR , "packet size is too small\n" );
124- return AVERROR (EINVAL );
125- }
114+ if (is_compr ) {
115+ esc -> fib_acc [0 ] = avpkt -> data [1 ] + 128 ;
116+ if (avctx -> channels == 2 )
117+ esc -> fib_acc [1 ] = avpkt -> data [2 + chan_size + 1 ] + 128 ;
118+ }
126119
127- /* the uncompressed starting value is contained in the first byte */
128- dst = esc -> samples ;
129- for (i = 0 ; i < avctx -> channels ; i ++ ) {
130- * (dst ++ ) = buf [0 ]+ 128 ;
131- delta_decode (dst , buf + 1 , buf_size / avctx -> channels - 1 , (buf [0 ]+ 128 )& 0xFF , esc -> table );
132- buf += buf_size / avctx -> channels ;
133- dst += n / avctx -> channels - 1 ;
120+ esc -> data_idx = 0 ;
121+ esc -> data_size = chan_size ;
122+ if (!(esc -> data [0 ] = av_malloc (chan_size )))
123+ return AVERROR (ENOMEM );
124+ if (avctx -> channels == 2 ) {
125+ if (!(esc -> data [1 ] = av_malloc (chan_size ))) {
126+ av_freep (& esc -> data [0 ]);
127+ return AVERROR (ENOMEM );
134128 }
135- } else {
136- raw_decode (esc -> samples , avpkt -> data , esc -> samples_size );
137129 }
130+ memcpy (esc -> data [0 ], & avpkt -> data [hdr_size ], chan_size );
131+ if (avctx -> channels == 2 )
132+ memcpy (esc -> data [1 ], & avpkt -> data [2 * hdr_size + chan_size ], chan_size );
133+ }
134+ if (!esc -> data [0 ]) {
135+ av_log (avctx , AV_LOG_ERROR , "unexpected empty packet\n" );
136+ return AVERROR (EINVAL );
137+ }
138+
139+ /* decode next piece of data from the buffer */
140+ buf_size = FFMIN (MAX_FRAME_SIZE , esc -> data_size - esc -> data_idx );
141+ if (buf_size <= 0 ) {
142+ * got_frame_ptr = 0 ;
143+ return avpkt -> size ;
138144 }
139145
140146 /* get output buffer */
141- av_assert1 (!(esc -> samples_size % avctx -> channels || esc -> samples_idx % avctx -> channels ));
142- esc -> frame .nb_samples = FFMIN (MAX_FRAME_SIZE , esc -> samples_size - esc -> samples_idx ) / avctx -> channels ;
147+ esc -> frame .nb_samples = buf_size * (is_compr + 1 );
143148 if ((ret = avctx -> get_buffer (avctx , & esc -> frame )) < 0 ) {
144149 av_log (avctx , AV_LOG_ERROR , "get_buffer() failed\n" );
145150 return ret ;
146151 }
147152
153+ for (ch = 0 ; ch < avctx -> channels ; ch ++ ) {
154+ if (is_compr ) {
155+ delta_decode (esc -> frame .data [ch ], & esc -> data [ch ][esc -> data_idx ],
156+ buf_size , & esc -> fib_acc [ch ], esc -> table );
157+ } else {
158+ raw_decode (esc -> frame .data [ch ], & esc -> data [ch ][esc -> data_idx ],
159+ buf_size );
160+ }
161+ }
162+
163+ esc -> data_idx += buf_size ;
164+
148165 * got_frame_ptr = 1 ;
149166 * (AVFrame * )data = esc -> frame ;
150167
151- out_data_size = esc -> frame .nb_samples ;
152- for (ch = 0 ; ch < avctx -> channels ; ch ++ ) {
153- src = esc -> samples + esc -> samples_idx / avctx -> channels + ch * esc -> samples_size / avctx -> channels ;
154- memcpy (esc -> frame .data [ch ], src , out_data_size );
155- }
156- out_data_size *= avctx -> channels ;
157- esc -> samples_idx += out_data_size ;
158-
159- return esc -> table ?
160- (avctx -> frame_number == 0 )* 2 + out_data_size / 2 :
161- out_data_size ;
168+ return ((avctx -> frame_number == 0 )* hdr_size + buf_size )* avctx -> channels ;
162169}
163170
164171static av_cold int eightsvx_decode_init (AVCodecContext * avctx )
@@ -191,9 +198,10 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
191198{
192199 EightSvxContext * esc = avctx -> priv_data ;
193200
194- av_freep (& esc -> samples );
195- esc -> samples_size = 0 ;
196- esc -> samples_idx = 0 ;
201+ av_freep (& esc -> data [0 ]);
202+ av_freep (& esc -> data [1 ]);
203+ esc -> data_size = 0 ;
204+ esc -> data_idx = 0 ;
197205
198206 return 0 ;
199207}
0 commit comments