av_cold int ff_h263_decode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; ff_mpv_common_end(s); return 0; }
static av_cold int h261_decode_end(AVCodecContext *avctx) { H261Context *h = avctx->priv_data; MpegEncContext *s = &h->s; ff_mpv_common_end(s); return 0; }
static int h261_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; H261Context *h = avctx->priv_data; MpegEncContext *s = &h->s; int ret; AVFrame *pict = data; av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); av_dlog(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); s->flags = avctx->flags; s->flags2 = avctx->flags2; h->gob_start_code_skipped = 0; retry: init_get_bits(&s->gb, buf, buf_size * 8); if (!s->context_initialized) // we need the IDCT permutaton for reading a custom matrix ff_mpv_idct_init(s); ret = h261_decode_picture_header(h); /* skip if the header was thrashed */ if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; } if (s->width != avctx->coded_width || s->height != avctx->coded_height) { ParseContext pc = s->parse_context; // FIXME move this demuxing hack to libavformat s->parse_context.buffer = 0; ff_mpv_common_end(s); s->parse_context = pc; } if (!s->context_initialized) { if ((ret = ff_mpv_common_init(s)) < 0) return ret; ret = ff_set_dimensions(avctx, s->width, s->height); if (ret < 0) return ret; goto retry; } // for skipping the frame s->current_picture.f->pict_type = s->pict_type; s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); if (ff_mpv_frame_start(s, avctx) < 0) return -1; ff_mpeg_er_frame_start(s); /* decode each macroblock */ s->mb_x = 0; s->mb_y = 0; while (h->gob_number < (s->mb_height == 18 ? 12 : 5)) { if (h261_resync(h) < 0) break; h261_decode_gob(h); } ff_mpv_frame_end(s); av_assert0(s->current_picture.f->pict_type == s->current_picture_ptr->f->pict_type); av_assert0(s->current_picture.f->pict_type == s->pict_type); if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) return ret; ff_print_debug_info(s, s->current_picture_ptr, pict); *got_frame = 1; return get_consumed_bytes(s, buf_size); }
static int rv20_decode_picture_header(RVDecContext *rv) { MpegEncContext *s = &rv->m; int seq, mb_pos, i, ret; int rpr_bits; i = get_bits(&s->gb, 2); switch (i) { case 0: s->pict_type = AV_PICTURE_TYPE_I; break; case 1: s->pict_type = AV_PICTURE_TYPE_I; break; // hmm ... case 2: s->pict_type = AV_PICTURE_TYPE_P; break; case 3: s->pict_type = AV_PICTURE_TYPE_B; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n"); return AVERROR_INVALIDDATA; } if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) { av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n"); return AVERROR_INVALIDDATA; } if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n"); return AVERROR_INVALIDDATA; } s->qscale = get_bits(&s->gb, 5); if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n"); return AVERROR_INVALIDDATA; } if (RV_GET_MINOR_VER(rv->sub_id) >= 2) s->loop_filter = get_bits1(&s->gb); if (RV_GET_MINOR_VER(rv->sub_id) <= 1) seq = get_bits(&s->gb, 8) << 7; else seq = get_bits(&s->gb, 13) << 2; rpr_bits = s->avctx->extradata[1] & 7; if (rpr_bits) { int f, new_w, new_h; rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3); f = get_bits(&s->gb, rpr_bits); if (f) { if (s->avctx->extradata_size < 8 + 2 * f) { av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n"); return AVERROR_INVALIDDATA; } new_w = 4 * ((uint8_t *) s->avctx->extradata)[6 + 2 * f]; new_h = 4 * ((uint8_t *) s->avctx->extradata)[7 + 2 * f]; } else { new_w = rv->orig_width; new_h = rv->orig_height; } if (new_w != s->width || new_h != s->height) { av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h); ff_mpv_common_end(s); ret = ff_set_dimensions(s->avctx, new_w, new_h); if (ret < 0) return ret; s->width = new_w; s->height = new_h; if ((ret = ff_mpv_common_init(s)) < 0) return ret; } if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits); } } else if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)