| 553 | } |
| 554 | |
| 555 | static int amf_decode_frame(AVCodecContext *avctx, struct AVFrame *frame) |
| 556 | { |
| 557 | AMFDecoderContext *ctx = avctx->priv_data; |
| 558 | AMFBuffer *buf; |
| 559 | AMF_RESULT res; |
| 560 | int got_frame = 0; |
| 561 | AVPacket *avpkt = ctx->in_pkt; |
| 562 | |
| 563 | if (!ctx->decoder) |
| 564 | return AVERROR(EINVAL); |
| 565 | |
| 566 | // get packet if needed |
| 567 | if(!ctx->drain){ |
| 568 | if(ctx->resolution_changed) |
| 569 | ctx->resolution_changed = 0; |
| 570 | else{ |
| 571 | int ret; |
| 572 | av_packet_unref(avpkt); |
| 573 | ret = ff_decode_get_packet(avctx, avpkt); |
| 574 | if (ret < 0 && ret != AVERROR_EOF) |
| 575 | return ret; |
| 576 | if (ret == AVERROR_EOF) { |
| 577 | //nothing to consume, start external drain |
| 578 | ctx->decoder->pVtbl->Drain(ctx->decoder); |
| 579 | ctx->drain = 1; |
| 580 | } |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | if(!ctx->drain){ |
| 585 | // submit frame |
| 586 | res = amf_buffer_from_packet(avctx, avpkt, &buf); |
| 587 | AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, 0, "Cannot convert AVPacket to AMFbuffer"); |
| 588 | do{ |
| 589 | res = ctx->decoder->pVtbl->SubmitInput(ctx->decoder, (AMFData*) buf); |
| 590 | if(res == AMF_DECODER_NO_FREE_SURFACES) |
| 591 | { |
| 592 | av_usleep(100); |
| 593 | } |
| 594 | } while (res == AMF_DECODER_NO_FREE_SURFACES); |
| 595 | |
| 596 | buf->pVtbl->Release(buf); |
| 597 | |
| 598 | if(res == AMF_DECODER_NO_FREE_SURFACES) { |
| 599 | // input is not consumed, need to QueryOutput and submit again |
| 600 | av_log(avctx, AV_LOG_VERBOSE, "SubmitInput() returned NO_FREE_SURFACES and came out of loop - should never happen\n"); |
| 601 | res = AMF_OK; |
| 602 | } else if (res == AMF_RESOLUTION_CHANGED) { |
| 603 | //input is not consumed, start internal drain |
| 604 | ctx->decoder->pVtbl->Drain(ctx->decoder); |
| 605 | ctx->drain = 1; |
| 606 | // process resolution_changed when internal drain is complete |
| 607 | ctx->resolution_changed = 1; |
| 608 | res = AMF_OK; |
| 609 | } else if (res != AMF_OK && res != AMF_NEED_MORE_INPUT && res != AMF_REPEAT) { |
| 610 | av_log(avctx, AV_LOG_ERROR, "SubmitInput() returned error %d\n", res); |
| 611 | return AVERROR(EINVAL); |
| 612 | } |
nothing calls this directly
no test coverage detected