use zm_av_send_packet_receive_frame and fixup hwaccel support

This commit is contained in:
Isaac Connor 2021-01-07 15:12:27 -05:00
parent 13d7e612e3
commit 09264a52ff
1 changed files with 25 additions and 52 deletions

View File

@ -26,7 +26,6 @@ using namespace std;
ZMPacket::ZMPacket() : ZMPacket::ZMPacket() :
keyframe(0), keyframe(0),
// frame from decoded packet, to be used in generating image
in_frame(nullptr), in_frame(nullptr),
out_frame(nullptr), out_frame(nullptr),
timestamp(nullptr), timestamp(nullptr),
@ -44,7 +43,6 @@ ZMPacket::ZMPacket() :
ZMPacket::ZMPacket(ZMPacket &p) : ZMPacket::ZMPacket(ZMPacket &p) :
keyframe(0), keyframe(0),
// frame from decoded packet, to be used in generating image
in_frame(nullptr), in_frame(nullptr),
out_frame(nullptr), out_frame(nullptr),
timestamp(nullptr), timestamp(nullptr),
@ -67,11 +65,9 @@ ZMPacket::ZMPacket(ZMPacket &p) :
ZMPacket::~ZMPacket() { ZMPacket::~ZMPacket() {
zm_av_packet_unref(&packet); zm_av_packet_unref(&packet);
if ( in_frame ) { if ( in_frame ) {
//av_free(frame->data);
av_frame_free(&in_frame); av_frame_free(&in_frame);
} }
if ( out_frame ) { if ( out_frame ) {
//av_free(frame->data);
av_frame_free(&out_frame); av_frame_free(&out_frame);
} }
if ( buffer ) { if ( buffer ) {
@ -81,28 +77,26 @@ ZMPacket::~ZMPacket() {
delete analysis_image; delete analysis_image;
analysis_image = nullptr; analysis_image = nullptr;
} }
// We assume the image was allocated elsewhere, so we just unref it. if ( image and !image->IsBufferHeld() ) {
if ( image_index == -1 ) {
delete image; delete image;
delete timestamp;
} }
image = nullptr; image = nullptr;
timestamp = nullptr; if ( timestamp ) {
delete timestamp;
timestamp = nullptr;
}
} }
// deprecated
void ZMPacket::reset() { void ZMPacket::reset() {
//Debug(2,"reset");
zm_av_packet_unref(&packet); zm_av_packet_unref(&packet);
if ( in_frame ) { if ( in_frame ) {
//Debug(4,"reset frame");
av_frame_free(&in_frame); av_frame_free(&in_frame);
} }
if ( out_frame ) { if ( out_frame ) {
//Debug(4,"reset frame");
av_frame_free(&out_frame); av_frame_free(&out_frame);
} }
if ( buffer ) { if ( buffer ) {
//Debug(4,"freeing buffer");
av_freep(&buffer); av_freep(&buffer);
} }
if ( analysis_image ) { if ( analysis_image ) {
@ -128,58 +122,37 @@ int ZMPacket::decode(AVCodecContext *ctx) {
in_frame = zm_av_frame_alloc(); in_frame = zm_av_frame_alloc();
} }
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) int ret = zm_send_packet_receive_frame(ctx, in_frame, packet);
Debug(4, "send_packet");
int ret = avcodec_send_packet(ctx, &packet);
if ( ret < 0 ) { if ( ret < 0 ) {
Error("Unable to send packet: %s", av_make_error_string(ret).c_str()); if ( AVERROR(EAGAIN) != ret ) {
Warning("Unable to receive frame : code %d %s.",
ret, av_make_error_string(ret).c_str());
}
av_frame_free(&in_frame); av_frame_free(&in_frame);
return 0; return 0;
} }
#if HAVE_AVUTIL_HWCONTEXT_H #if HAVE_LIBAVUTIL_HWCONTEXT_H
if ( hwaccel ) { #if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0)
ret = avcodec_receive_frame(ctx, hwFrame); if ( (ctx->pix_fmt != in_frame->format) ) {
Debug(1, "Have different format. Assuming hwaccel");
AVFrame *new_frame = zm_av_frame_alloc();
/* retrieve data from GPU to CPU */
ret = av_hwframe_transfer_data(in_frame, new_frame, 0);
if ( ret < 0 ) { if ( ret < 0 ) {
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str()); Error("Unable to transfer frame: %s, continuing",
av_make_error_string(ret).c_str());
av_frame_free(&in_frame); av_frame_free(&in_frame);
av_frame_free(&new_frame);
return 0; return 0;
} }
ret = av_hwframe_transfer_data(frame, hwFrame, 0); zm_dump_video_frame(new_frame, "After hwtransfer");
if ( ret < 0 ) {
Error("Unable to transfer frame: %s", av_make_error_string(ret).c_str());
av_frame_free(&in_frame);
return 0;
}
} else {
#endif
Debug(4, "receive_frame");
ret = avcodec_receive_frame(ctx, in_frame);
if ( ret < 0 ) {
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str());
av_frame_free(&in_frame);
Error("Unable to receive frame: %s %p", av_make_error_string(ret).c_str(), in_frame);
return 0; new_frame->pts = in_frame->pts;
} av_frame_free(&in_frame);
in_frame = new_frame;
#if HAVE_AVUTIL_HWCONTEXT_H
} }
#endif #endif
# else
int frameComplete = 0;
int ret = zm_avcodec_decode_video(ctx, in_frame, &frameComplete, &packet);
if ( ret < 0 ) {
Error("Unable to decode frame at frame %s", av_make_error_string(ret).c_str());
av_frame_free(&in_frame);
return 0;
}
if ( !frameComplete ) {
Debug(1, "incomplete frame?");
av_frame_free(&in_frame);
return 0;
}
#endif #endif
return 1; return 1;
} // end ZMPacket::decode } // end ZMPacket::decode