On Thu, Mar 14, 2013 at 4:17 PM, Janne Grunau <[email protected]> wrote:
> Allows use of AVHWAccel based decoders with frame based multithreading.
> The decoders will be forced into an non-concurrent mode by delaying
> ff_thread_finish_setup() calls after decoding of the current frame
> is finished.
>
> This wastes memory by unnecessarily using multiple threads and thus
> copies of the decoder context but allows seamless switching between
> hardware accelerated and frame threaded software decoding when the
> hardware decoder does not support the stream.
> ---
>  libavcodec/h263dec.c | 6 +++++-
>  libavcodec/h264.c    | 9 +++++----
>  libavcodec/mpeg12.c  | 5 ++++-
>  libavcodec/pthread.c | 3 +++
>  libavcodec/version.h | 2 +-
>  5 files changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
> index 28fb2db..e8edad7 100644
> --- a/libavcodec/h263dec.c
> +++ b/libavcodec/h263dec.c
> @@ -627,7 +627,8 @@ retry:
>      if(ff_MPV_frame_start(s, avctx) < 0)
>          return -1;
>
> -    if (!s->divx_packed) ff_thread_finish_setup(avctx);
> +    if (!s->divx_packed && !avctx->hwaccel)
> +        ff_thread_finish_setup(avctx);
>
>      if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & 
> CODEC_CAP_HWACCEL_VDPAU)) {
>          ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - 
> s->gb.buffer);
> @@ -720,6 +721,9 @@ intrax8_decoded:
>
>      ff_MPV_frame_end(s);
>
> +    if (!s->divx_packed && avctx->hwaccel)
> +        ff_thread_finish_setup(avctx);
> +
>      assert(s->current_picture.f.pict_type == 
> s->current_picture_ptr->f.pict_type);
>      assert(s->current_picture.f.pict_type == s->pict_type);
>      if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index 9b196c7..db30e3c 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -4453,7 +4453,8 @@ again:
>                      (h->sei_recovery_frame_cnt >= 0);
>
>                  if (h->current_slice == 1) {
> -                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
> +                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) &&
> +                        !h->avctx->hwaccel)
>                          decode_postinit(h, nal_index >= nals_needed);
>
>                      if (h->avctx->hwaccel &&
> @@ -4665,11 +4666,11 @@ out:
>
>      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
>          (h->mb_y >= h->mb_height && h->mb_height)) {
> -        if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
> -            decode_postinit(h, 1);
> -
>          field_end(h, 0);
>
> +        if (avctx->flags2 & CODEC_FLAG2_CHUNKS || h->avctx->hwaccel)
> +            decode_postinit(h, 1);
> +
>          if (!h->next_output_pic) {
>              /* Wait for second field. */
>              *got_frame = 0;
> diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
> index c32055d..c7236a0 100644
> --- a/libavcodec/mpeg12.c
> +++ b/libavcodec/mpeg12.c
> @@ -1603,7 +1603,8 @@ static int mpeg_field_start(MpegEncContext *s, const 
> uint8_t *buf, int buf_size)
>              return AVERROR(ENOMEM);
>          memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
>
> -        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
> +        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME) &&
> +            !avctx->hwaccel)
>              ff_thread_finish_setup(avctx);

mpeg2 has no frame threading, why is this check in here in the first place?

>      } else { // second field
>          int i;
> @@ -1925,6 +1926,8 @@ static int slice_end(AVCodecContext *avctx, AVFrame 
> *pict)
>      if (s->avctx->hwaccel) {
>          if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
>              av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to 
> decode picture\n");
> +        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
> +            ff_thread_finish_setup(avctx);
>      }
>
>      if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
> diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
> index 7061090..7e6f940 100644
> --- a/libavcodec/pthread.c
> +++ b/libavcodec/pthread.c
> @@ -428,6 +428,9 @@ static int update_context_from_thread(AVCodecContext 
> *dst, AVCodecContext *src,
>          dst->colorspace  = src->colorspace;
>          dst->color_range = src->color_range;
>          dst->chroma_sample_location = src->chroma_sample_location;
> +
> +        dst->hwaccel = src->hwaccel;
> +        dst->hwaccel_context = src->hwaccel_context;
>      }
>
>      if (for_user) {
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index 8b4fbce..394bf1a 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -27,7 +27,7 @@
>   */
>
>  #define LIBAVCODEC_VERSION_MAJOR 55
> -#define LIBAVCODEC_VERSION_MINOR  0
> +#define LIBAVCODEC_VERSION_MINOR  1
>  #define LIBAVCODEC_VERSION_MICRO  0
>
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> --
> 1.8.1.5
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to