+static void vp3_decode_flush(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ if (s->golden_frame.data[0]) {
+ if (s->golden_frame.data[0] == s->last_frame.data[0])
+ memset(&s->last_frame, 0, sizeof(AVFrame));
+ if (s->current_frame.data[0] == s->golden_frame.data[0])
+ memset(&s->current_frame, 0, sizeof(AVFrame));
+ ff_thread_release_buffer(avctx, &s->golden_frame);
+ }
+ if (s->last_frame.data[0]) {
+ if (s->current_frame.data[0] == s->last_frame.data[0])
+ memset(&s->current_frame, 0, sizeof(AVFrame));
+ ff_thread_release_buffer(avctx, &s->last_frame);
+ }
+ if (s->current_frame.data[0])
+ ff_thread_release_buffer(avctx, &s->current_frame);
+}
+
+static av_cold int vp3_decode_end(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int i;
+
+ av_freep(&s->superblock_coding);
+ av_freep(&s->all_fragments);
+ av_freep(&s->coded_fragment_list[0]);
+ av_freep(&s->dct_tokens_base);
+ av_freep(&s->superblock_fragments);
+ av_freep(&s->macroblock_coding);
+ av_freep(&s->motion_val[0]);
+ av_freep(&s->motion_val[1]);
+ av_freep(&s->edge_emu_buffer);
+
+ if (avctx->internal->is_copy)
+ return 0;
+
+ for (i = 0; i < 16; i++) {
+ ff_free_vlc(&s->dc_vlc[i]);
+ ff_free_vlc(&s->ac_vlc_1[i]);
+ ff_free_vlc(&s->ac_vlc_2[i]);
+ ff_free_vlc(&s->ac_vlc_3[i]);
+ ff_free_vlc(&s->ac_vlc_4[i]);
+ }
+
+ ff_free_vlc(&s->superblock_run_length_vlc);
+ ff_free_vlc(&s->fragment_run_length_vlc);
+ ff_free_vlc(&s->mode_code_vlc);
+ ff_free_vlc(&s->motion_vector_vlc);
+
+ /* release all frames */
+ vp3_decode_flush(avctx);
+
+ return 0;
+}
+