X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh263dec.c;h=dafa54d8d4c34a06d573d03fabc0554467169e2a;hb=e847cabb60a29c354512664022ad6833a907bf1b;hp=5608b6324564f347aa84f49e5491956bd074698c;hpb=706d2c66e8e59cfda32e57713bc37e5558a25815;p=ffmpeg diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 5608b632456..dafa54d8d4c 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -28,12 +28,14 @@ #define UNCHECKED_BITSTREAM_READER 1 #include "libavutil/cpu.h" +#include "libavutil/video_enc_params.h" + #include "avcodec.h" #include "error_resilience.h" #include "flv.h" #include "h263.h" #include "h263_parser.h" -#include "hwaccel.h" +#include "hwconfig.h" #include "internal.h" #include "mpeg_er.h" #include "mpeg4video.h" @@ -47,6 +49,12 @@ static enum AVPixelFormat h263_get_format(AVCodecContext *avctx) { + /* MPEG-4 Studio Profile only, not supported by hardware */ + if (avctx->bits_per_raw_sample > 8) { + av_assert1(((MpegEncContext *)avctx->priv_data)->studio_profile); + return avctx->pix_fmt; + } + if (avctx->codec->id == AV_CODEC_ID_MSS2) return AV_PIX_FMT_YUV420P; @@ -67,7 +75,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) s->out_format = FMT_H263; // set defaults - ff_mpv_decode_defaults(s); ff_mpv_decode_init(s, avctx); s->quant_precision = 5; @@ -197,6 +204,11 @@ static int decode_slice(MpegEncContext *s) ff_set_qscale(s, s->qscale); + if (s->studio_profile) { + if ((ret = ff_mpeg4_decode_studio_slice_header(s->avctx->priv_data)) < 0) + return ret; + } + if (s->avctx->hwaccel) { const uint8_t *start = s->gb.buffer + get_bits_count(&s->gb) / 8; ret = s->avctx->hwaccel->decode_slice(s->avctx, start, s->gb.buffer_end - start); @@ -307,6 +319,7 @@ static int decode_slice(MpegEncContext *s) av_assert1(s->mb_x == 0 && s->mb_y == s->mb_height); + // Detect incorrect padding with wrong stuffing codes used by NEC N-02B if (s->codec_id == AV_CODEC_ID_MPEG4 && (s->workaround_bugs & FF_BUG_AUTODETECT) && get_bits_left(&s->gb) >= 48 && @@ -488,9 +501,9 @@ retry: GetBitContext gb; if (init_get_bits8(&gb, s->avctx->extradata, s->avctx->extradata_size) >= 0 ) - ff_mpeg4_decode_picture_header(avctx->priv_data, &gb); + ff_mpeg4_decode_picture_header(avctx->priv_data, &gb, 1); } - ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb); + ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb, 0); } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) { ret = ff_intel_h263_decode_picture_header(s); } else if (CONFIG_FLV_DECODER && s->h263_flv) { @@ -534,6 +547,8 @@ retry: if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) { if (ff_mpeg4_workaround_bugs(avctx) == 1) goto retry; + if (s->studio_profile != (s->idsp.idct == NULL)) + ff_mpv_idct_init(s); } /* After H.263 & MPEG-4 header decode we have the height, width, @@ -600,7 +615,7 @@ retry: if ((ret = ff_mpv_frame_start(s, avctx)) < 0) return ret; - if (!s->divx_packed) + if (!s->divx_packed && !avctx->hwaccel) ff_thread_finish_setup(avctx); if (avctx->hwaccel) { @@ -630,7 +645,7 @@ retry: slice_ret = decode_slice(s); while (s->mb_y < s->mb_height) { if (s->msmpeg4_version) { - if (s->slice_height == 0 || s->mb_x != 0 || + if (s->slice_height == 0 || s->mb_x != 0 || slice_ret < 0 || (s->mb_y % s->slice_height) != 0 || get_bits_left(&s->gb) < 0) break; } else { @@ -656,7 +671,8 @@ retry: av_assert1(s->bitstream_buffer_size == 0); frame_end: - ff_er_frame_end(&s->er); + if (!s->studio_profile) + ff_er_frame_end(&s->er); if (avctx->hwaccel) { ret = avctx->hwaccel->end_frame(avctx); @@ -728,6 +744,22 @@ const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = { AV_PIX_FMT_NONE }; +const AVCodecHWConfigInternal *const ff_h263_hw_config_list[] = { +#if CONFIG_H263_VAAPI_HWACCEL + HWACCEL_VAAPI(h263), +#endif +#if CONFIG_MPEG4_NVDEC_HWACCEL + HWACCEL_NVDEC(mpeg4), +#endif +#if CONFIG_MPEG4_VDPAU_HWACCEL + HWACCEL_VDPAU(mpeg4), +#endif +#if CONFIG_H263_VIDEOTOOLBOX_HWACCEL + HWACCEL_VIDEOTOOLBOX(h263), +#endif + NULL +}; + AVCodec ff_h263_decoder = { .name = "h263", .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), @@ -739,10 +771,11 @@ AVCodec ff_h263_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, + .hw_configs = ff_h263_hw_config_list, }; AVCodec ff_h263p_decoder = { @@ -756,20 +789,9 @@ AVCodec ff_h263p_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, - .hw_configs = (const AVCodecHWConfigInternal*[]) { -#if CONFIG_H263_VAAPI_HWACCEL - HWACCEL_VAAPI(h263), -#endif -#if CONFIG_MPEG4_VDPAU_HWACCEL - HWACCEL_VDPAU(mpeg4), -#endif -#if CONFIG_H263_VIDEOTOOLBOX_HWACCEL - HWACCEL_VIDEOTOOLBOX(h263), -#endif - NULL - }, + .hw_configs = ff_h263_hw_config_list, };