av_cold int ff_vp56_free_context(VP56Context *s) { AVCodecContext *avctx = s->avctx; int i; av_freep(&s->qscale_table); av_freep(&s->above_blocks); av_freep(&s->macroblocks); av_freep(&s->edge_emu_buffer_alloc); for (i = 0; i < 4; ++i) { if (s->frames[i].data[0]) avctx->release_buffer(avctx, &s->frames[i]); } return 0; }
int PrivateDecoderMPEG2::GetFrame(AVStream *stream, AVFrame *picture, int *got_picture_ptr, AVPacket *pkt) { AVCodecContext *avctx = stream->codec; *got_picture_ptr = 0; const mpeg2_info_t *info = mpeg2_info(mpeg2dec); mpeg2_buffer(mpeg2dec, pkt->data, pkt->data + pkt->size); while (1) { switch (mpeg2_parse(mpeg2dec)) { case STATE_SEQUENCE: // libmpeg2 needs three buffers to do its work. // We set up two prediction buffers here, from // the set of available video frames. mpeg2_custom_fbuf(mpeg2dec, 1); for (int i = 0; i < 2; i++) { avctx->get_buffer(avctx, picture); mpeg2_set_buf(mpeg2dec, picture->data, picture->opaque); } break; case STATE_PICTURE: // This sets up the third buffer for libmpeg2. // We use up one of the three buffers for each // frame shown. The frames get released once // they are drawn (outside this routine). avctx->get_buffer(avctx, picture); mpeg2_set_buf(mpeg2dec, picture->data, picture->opaque); break; case STATE_BUFFER: // We're finished with the buffer... if (partialFrames.size()) { AVFrame *frm = partialFrames.dequeue(); *got_picture_ptr = 1; *picture = *frm; delete frm; #if 0 QString msg(""); AvFormatDecoder *nd = (AvFormatDecoder *)(avctx->opaque); if (nd && nd->GetNVP() && nd->GetNVP()->getVideoOutput()) msg = nd->GetNVP()->getVideoOutput()->GetFrameStatus(); VERBOSE(VB_IMPORTANT, "ret frame: "<<picture->opaque <<" "<<msg); #endif } return pkt->size; case STATE_INVALID: // This is the error state. The decoder must be // reset on an error. Reset(); return -1; case STATE_SLICE: case STATE_END: case STATE_INVALID_END: if (info->display_fbuf) { bool exists = false; avframe_q::iterator it = partialFrames.begin(); for (; it != partialFrames.end(); ++it) if ((*it)->opaque == info->display_fbuf->id) exists = true; if (!exists) { AVFrame *frm = new AVFrame(); frm->data[0] = info->display_fbuf->buf[0]; frm->data[1] = info->display_fbuf->buf[1]; frm->data[2] = info->display_fbuf->buf[2]; frm->data[3] = NULL; frm->opaque = info->display_fbuf->id; frm->type = FF_BUFFER_TYPE_USER; frm->top_field_first = !!(info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST); frm->interlaced_frame = !(info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME); frm->repeat_pict = !!(info->display_picture->flags & #if CONFIG_LIBMPEG2EXTERNAL PIC_FLAG_REPEAT_FIRST_FIELD); #else PIC_FLAG_REPEAT_FIELD); #endif partialFrames.enqueue(frm); } } if (info->discard_fbuf) { bool exists = false; avframe_q::iterator it = partialFrames.begin(); for (; it != partialFrames.end(); ++it) { if ((*it)->opaque == info->discard_fbuf->id) { exists = true; (*it)->data[3] = (unsigned char*) 1; } } if (!exists) { AVFrame frame; frame.opaque = info->discard_fbuf->id; frame.type = FF_BUFFER_TYPE_USER; avctx->release_buffer(avctx, &frame); } } break; default: break; }