|
22 | 22 |
|
23 | 23 | #include "zm_logger.h" |
24 | 24 | #include "zm_monitor.h" |
| 25 | +#include "zm_signal.h" |
25 | 26 | #include "zm_time.h" |
26 | 27 |
|
27 | 28 | extern "C" { |
@@ -303,6 +304,7 @@ bool VideoStore::open() { |
303 | 304 | video_out_ctx->time_base = AV_TIME_BASE_Q; |
304 | 305 | video_out_ctx->codec_id = chosen_codec_data->codec_id; |
305 | 306 | video_out_ctx->pix_fmt = chosen_codec_data->hw_pix_fmt; |
| 307 | + video_out_ctx->sw_pix_fmt = chosen_codec_data->sw_pix_fmt; |
306 | 308 | Debug(1, "Setting pix fmt to %d %s", chosen_codec_data->hw_pix_fmt, av_get_pix_fmt_name(chosen_codec_data->hw_pix_fmt)); |
307 | 309 | const AVDictionaryEntry *opts_level = av_dict_get(opts, "level", nullptr, AV_DICT_MATCH_CASE); |
308 | 310 | if (opts_level) { |
@@ -334,7 +336,7 @@ bool VideoStore::open() { |
334 | 336 | * the motion of the chroma plane does not match the luma plane. */ |
335 | 337 | video_out_ctx->mb_decision = 2; |
336 | 338 | } |
337 | | - if (setup_hwaccel(video_out_ctx, |
| 339 | + if (0 and setup_hwaccel(video_out_ctx, |
338 | 340 | chosen_codec_data, hw_device_ctx, monitor->EncoderHWAccelDevice(), monitor->Width(), monitor->Height())) { |
339 | 341 | continue; |
340 | 342 | } |
@@ -1043,22 +1045,43 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet) |
1043 | 1045 | if (zm_packet->image) { |
1044 | 1046 | Debug(2, "Have an image, convert it"); |
1045 | 1047 | //Go straight to out frame |
1046 | | - swscale.Convert( |
1047 | | - zm_packet->image, |
1048 | | - zm_packet->out_frame->buf[0]->data, |
1049 | | - zm_packet->codec_imgsize, |
1050 | | - zm_packet->image->AVPixFormat(), |
1051 | | - chosen_codec_data->sw_pix_fmt, |
1052 | | - video_out_ctx->width, |
1053 | | - video_out_ctx->height |
1054 | | - ); |
| 1048 | + if ( |
| 1049 | + zm_packet->image->Width() == video_out_ctx->width |
| 1050 | + and |
| 1051 | + zm_packet->image->Height() == video_out_ctx->height |
| 1052 | + and |
| 1053 | + zm_packet->image->AVPixFormat() == chosen_codec_data->sw_pix_fmt |
| 1054 | + ) { |
| 1055 | + zm_packet->image->PopulateFrame(zm_packet->out_frame.get()); |
| 1056 | + } else { |
| 1057 | + swscale.Convert( |
| 1058 | + zm_packet->image, |
| 1059 | + zm_packet->out_frame->buf[0]->data, |
| 1060 | + zm_packet->codec_imgsize, |
| 1061 | + zm_packet->image->AVPixFormat(), |
| 1062 | + chosen_codec_data->sw_pix_fmt, |
| 1063 | + video_out_ctx->width, |
| 1064 | + video_out_ctx->height |
| 1065 | + ); |
| 1066 | + } |
1055 | 1067 | } else if (!zm_packet->in_frame) { |
1056 | 1068 | Debug(1, "Have neither in_frame or image in packet %d!", |
1057 | 1069 | zm_packet->image_index); |
1058 | 1070 | return 0; |
1059 | 1071 | } else { |
1060 | | - // Have in_frame.... may need to convert it to out_frame |
1061 | | - swscale.Convert(zm_packet->in_frame.get(), zm_packet->out_frame.get()); |
| 1072 | + if ( |
| 1073 | + zm_packet->in_frame->width == video_out_ctx->width |
| 1074 | + and |
| 1075 | + zm_packet->in_frame->height == video_out_ctx->height |
| 1076 | + and |
| 1077 | + static_cast<AVPixelFormat>(zm_packet->in_frame->format) == chosen_codec_data->sw_pix_fmt |
| 1078 | + ) { |
| 1079 | + zm_packet->out_frame = std::move(zm_packet->in_frame); |
| 1080 | + zm_packet->in_frame = nullptr; |
| 1081 | + } else { |
| 1082 | + // Have in_frame.... may need to convert it to out_frame |
| 1083 | + swscale.Convert(zm_packet->in_frame.get(), zm_packet->out_frame.get()); |
| 1084 | + } |
1062 | 1085 | } // end if no in_frame |
1063 | 1086 | } // end if no out_frame |
1064 | 1087 |
|
@@ -1154,14 +1177,20 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet) |
1154 | 1177 |
|
1155 | 1178 | // Some hwaccel codecs may get full if we only receive one pkt for one frame |
1156 | 1179 |
|
1157 | | - //int ret = zm_send_frame_receive_packet(video_out_ctx, frame, *opkt); |
1158 | | - int ret = avcodec_send_frame(video_out_ctx, frame); |
1159 | | - if (ret < 0) { |
1160 | | - Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str()); |
1161 | | - return ret; |
1162 | | - } |
1163 | | - while (true) { |
1164 | | - ret = avcodec_receive_packet(video_out_ctx, opkt.get()); |
| 1180 | + do { |
| 1181 | + int ret = avcodec_send_frame(video_out_ctx, frame); |
| 1182 | + if (ret == AVERROR(EAGAIN)) { |
| 1183 | + continue; |
| 1184 | + } |
| 1185 | + if (ret < 0) { |
| 1186 | + Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str()); |
| 1187 | + return ret; |
| 1188 | + } |
| 1189 | + break; |
| 1190 | + } while(!zm_terminate); |
| 1191 | + |
| 1192 | + while (!zm_terminate) { |
| 1193 | + int ret = avcodec_receive_packet(video_out_ctx, opkt.get()); |
1165 | 1194 | if (ret < 0) { |
1166 | 1195 | if (ret != AVERROR(EAGAIN)) { |
1167 | 1196 | Error("Could not receive packet (error %d = %s)", ret, av_make_error_string(ret).c_str()); |
|
0 commit comments