Instead of a single AVFrame. Will be useful in future commits, where we will want to produce multiple output frames for a single coded frame.
Showing the changes to libavcodec (4 of 4 files). Show all
Unified · Split
| @@ -431,7 +431,7 @@ OBJS-$(CONFIG_HCA_DECODER) += hcadec.o · 430 unmodified lines | |||
| 431 | OBJS-$(CONFIG_HCOM_DECODER) += hcom.o | 431 | OBJS-$(CONFIG_HCOM_DECODER) += hcom.o |
| 432 | OBJS-$(CONFIG_HDR_DECODER) += hdrdec.o | 432 | OBJS-$(CONFIG_HDR_DECODER) += hdrdec.o |
| 433 | OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o | 433 | OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o |
| 434 | OBJS-$(CONFIG_HEVC_DECODER) += aom_film_grain.o h274.o | 434 | OBJS-$(CONFIG_HEVC_DECODER) += aom_film_grain.o h274.o container_fifo.o |
| 435 | OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o | 435 | OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o |
| 436 | OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o | 436 | OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o |
| 437 | OBJS-$(CONFIG_HEVC_D3D12VA_ENCODER) += d3d12va_encode_hevc.o h265_profile_level.o \ | 437 | OBJS-$(CONFIG_HEVC_D3D12VA_ENCODER) += d3d12va_encode_hevc.o h265_profile_level.o \ |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | |||
| 40 | #include "bswapdsp.h" | 40 | #include "bswapdsp.h" |
| 41 | #include "cabac_functions.h" | 41 | #include "cabac_functions.h" |
| 42 | #include "codec_internal.h" | 42 | #include "codec_internal.h" |
| 43 | #include "container_fifo.h" | ||
| 43 | #include "decode.h" | 44 | #include "decode.h" |
| 44 | #include "golomb.h" | 45 | #include "golomb.h" |
| 45 | #include "hevc.h" | 46 | #include "hevc.h" |
| @@ -3007,6 +3008,10 @@ static int hevc_frame_start(HEVCContext *s) · 2961 unmodified lines | |||
| 3007 | s->cur_frame->frame_grain->height = s->cur_frame->f->height; | 3008 | s->cur_frame->frame_grain->height = s->cur_frame->f->height; |
| 3008 | if ((ret = ff_thread_get_buffer(s->avctx, s->cur_frame->frame_grain, 0)) < 0) | 3009 | if ((ret = ff_thread_get_buffer(s->avctx, s->cur_frame->frame_grain, 0)) < 0) |
| 3009 | goto fail; | 3010 | goto fail; |
| 3011 | |||
| 3012 | ret = av_frame_copy_props(s->cur_frame->frame_grain, s->cur_frame->f); | ||
| 3013 | if (ret < 0) | ||
| 3014 | goto fail; | ||
| 3010 | } | 3015 | } |
| 3011 | 3016 | ||
| 3012 | s->cur_frame->f->pict_type = 3 - s->sh.slice_type; | 3017 | s->cur_frame->f->pict_type = 3 - s->sh.slice_type; |
| @@ -3014,8 +3019,7 @@ static int hevc_frame_start(HEVCContext *s) · 1 unmodified line | |||
| 3014 | if (!IS_IRAP(s)) | 3019 | if (!IS_IRAP(s)) |
| 3015 | ff_hevc_bump_frame(s); | 3020 | ff_hevc_bump_frame(s); |
| 3016 | 3021 | ||
| 3017 | av_frame_unref(s->output_frame); | 3022 | ret = ff_hevc_output_frame(s, 0); |
| 3018 | ret = ff_hevc_output_frame(s, s->output_frame, 0); | ||
| 3019 | if (ret < 0) | 3023 | if (ret < 0) |
| 3020 | goto fail; | 3024 | goto fail; |
| 3021 | 3025 | ||
| @@ -3415,13 +3419,16 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) · 393 unmodified lines | |||
| 3415 | uint8_t *sd; | 3419 | uint8_t *sd; |
| 3416 | size_t sd_size; | 3420 | size_t sd_size; |
| 3417 | 3421 | ||
| 3422 | if (ff_container_fifo_can_read(s->output_fifo)) | ||
| 3423 | goto do_output; | ||
| 3424 | |||
| 3418 | av_packet_unref(avpkt); | 3425 | av_packet_unref(avpkt); |
| 3419 | ret = ff_decode_get_packet(avctx, avpkt); | 3426 | ret = ff_decode_get_packet(avctx, avpkt); |
| 3420 | if (ret == AVERROR_EOF) { | 3427 | if (ret == AVERROR_EOF) { |
| 3421 | ret = ff_hevc_output_frame(s, frame, 1); | 3428 | ret = ff_hevc_output_frame(s, 1); |
| 3422 | if (ret < 0) | 3429 | if (ret < 0) |
| 3423 | return ret; | 3430 | return ret; |
| 3424 | return (ret > 0) ? 0 : AVERROR_EOF; | 3431 | goto do_output; |
| 3425 | } else if (ret < 0) | 3432 | } else if (ret < 0) |
| 3426 | return ret; | 3433 | return ret; |
| 3427 | 3434 | ||
| @@ -3446,12 +3453,15 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) · 18 unmodified lines | |||
| 3446 | if (ret < 0) | 3453 | if (ret < 0) |
| 3447 | return ret; | 3454 | return ret; |
| 3448 | 3455 | ||
| 3449 | if (s->output_frame->buf[0]) { | 3456 | do_output: |
| 3450 | av_frame_move_ref(frame, s->output_frame); | 3457 | if (ff_container_fifo_read(s->output_fifo, frame) >= 0) { |
| 3458 | if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) | ||
| 3459 | av_frame_remove_side_data(frame, AV_FRAME_DATA_FILM_GRAIN_PARAMS); | ||
| 3460 | |||
| 3451 | return 0; | 3461 | return 0; |
| 3452 | } | 3462 | } |
| 3453 | 3463 | ||
| 3454 | return AVERROR(EAGAIN); | 3464 | return avci->draining ? AVERROR_EOF : AVERROR(EAGAIN); |
| 3455 | } | 3465 | } |
| 3456 | 3466 | ||
| 3457 | static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src) | 3467 | static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src) |
| @@ -3503,7 +3513,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) · 45 unmodified lines | |||
| 3503 | av_freep(&s->sao_pixel_buffer_h[i]); | 3513 | av_freep(&s->sao_pixel_buffer_h[i]); |
| 3504 | av_freep(&s->sao_pixel_buffer_v[i]); | 3514 | av_freep(&s->sao_pixel_buffer_v[i]); |
| 3505 | } | 3515 | } |
| 3506 | av_frame_free(&s->output_frame); | 3516 | |
| 3517 | ff_container_fifo_free(&s->output_fifo); | ||
| 3507 | 3518 | ||
| 3508 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { | 3519 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
| 3509 | ff_hevc_unref_frame(&s->DPB[i], ~0); | 3520 | ff_hevc_unref_frame(&s->DPB[i], ~0); |
| @@ -3541,8 +3552,8 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) · 31 unmodified lines | |||
| 3541 | s->local_ctx[0].logctx = avctx; | 3552 | s->local_ctx[0].logctx = avctx; |
| 3542 | s->local_ctx[0].common_cabac_state = &s->cabac; | 3553 | s->local_ctx[0].common_cabac_state = &s->cabac; |
| 3543 | 3554 | ||
| 3544 | s->output_frame = av_frame_alloc(); | 3555 | s->output_fifo = ff_container_fifo_alloc_avframe(0); |
| 3545 | if (!s->output_frame) | 3556 | if (!s->output_fifo) |
| 3546 | return AVERROR(ENOMEM); | 3557 | return AVERROR(ENOMEM); |
| 3547 | 3558 | ||
| 3548 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { | 3559 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
| @@ -457,7 +457,7 @@ typedef struct HEVCContext { · 456 unmodified lines | |||
| 457 | /** 1 if the independent slice segment header was successfully parsed */ | 457 | /** 1 if the independent slice segment header was successfully parsed */ |
| 458 | uint8_t slice_initialized; | 458 | uint8_t slice_initialized; |
| 459 | 459 | ||
| 460 | AVFrame *output_frame; | 460 | struct ContainerFifo *output_fifo; |
| 461 | uint8_t *sao_pixel_buffer_h[3]; | 461 | uint8_t *sao_pixel_buffer_h[3]; |
| 462 | uint8_t *sao_pixel_buffer_v[3]; | 462 | uint8_t *sao_pixel_buffer_v[3]; |
| 463 | 463 | ||
| @@ -636,7 +636,7 @@ static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type) · 172 unmodified lines | |||
| 636 | * Find next frame in output order and put a reference to it in frame. | 636 | * Find next frame in output order and put a reference to it in frame. |
| 637 | * @return 1 if a frame was output, 0 otherwise | 637 | * @return 1 if a frame was output, 0 otherwise |
| 638 | */ | 638 | */ |
| 639 | int ff_hevc_output_frame(HEVCContext *s, AVFrame *frame, int flush); | 639 | int ff_hevc_output_frame(HEVCContext *s, int flush); |
| 640 | 640 | ||
| 641 | void ff_hevc_bump_frame(HEVCContext *s); | 641 | void ff_hevc_bump_frame(HEVCContext *s); |
| 642 | 642 | ||
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include "libavutil/mem.h" | 24 | #include "libavutil/mem.h" |
| 25 | 25 | ||
| 26 | #include "container_fifo.h" | ||
| 26 | #include "decode.h" | 27 | #include "decode.h" |
| 27 | #include "hevc.h" | 28 | #include "hevc.h" |
| 28 | #include "hevcdec.h" | 29 | #include "hevcdec.h" |
| @@ -171,7 +172,7 @@ static void unref_missing_refs(HEVCContext *s) · 142 unmodified lines | |||
| 171 | } | 172 | } |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) | 175 | int ff_hevc_output_frame(HEVCContext *s, int flush) |
| 175 | { | 176 | { |
| 176 | if (IS_IRAP(s) && s->no_rasl_output_flag == 1) { | 177 | if (IS_IRAP(s) && s->no_rasl_output_flag == 1) { |
| 177 | const static int mask = HEVC_FRAME_FLAG_BUMPING | HEVC_FRAME_FLAG_OUTPUT; | 178 | const static int mask = HEVC_FRAME_FLAG_BUMPING | HEVC_FRAME_FLAG_OUTPUT; |
| @@ -211,7 +212,8 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) · 33 unmodified lines | |||
| 211 | if (nb_output) { | 212 | if (nb_output) { |
| 212 | HEVCFrame *frame = &s->DPB[min_idx]; | 213 | HEVCFrame *frame = &s->DPB[min_idx]; |
| 213 | 214 | ||
| 214 | ret = av_frame_ref(out, frame->needs_fg ? frame->frame_grain : frame->f); | 215 | ret = ff_container_fifo_write(s->output_fifo, |
| 216 | frame->needs_fg ? frame->frame_grain : frame->f); | ||
| 215 | if (frame->flags & HEVC_FRAME_FLAG_BUMPING) | 217 | if (frame->flags & HEVC_FRAME_FLAG_BUMPING) |
| 216 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); | 218 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); |
| 217 | else | 219 | else |
| @@ -219,12 +221,6 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) · 1 unmodified line | |||
| 219 | if (ret < 0) | 221 | if (ret < 0) |
| 220 | return ret; | 222 | return ret; |
| 221 | 223 | ||
| 222 | if (frame->needs_fg && (ret = av_frame_copy_props(out, frame->f)) < 0) | ||
| 223 | return ret; | ||
| 224 | |||
| 225 | if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) | ||
| 226 | av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS); | ||
| 227 | |||
| 228 | av_log(s->avctx, AV_LOG_DEBUG, | 224 | av_log(s->avctx, AV_LOG_DEBUG, |
| 229 | "Output frame with POC %d.\n", frame->poc); | 225 | "Output frame with POC %d.\n", frame->poc); |
| 230 | return 1; | 226 | return 1; |