41 {
42 if (input_video_buffer_.empty()) {
43 AERROR <<
"error: failed to read from input video file";
44 return false;
45 }
46 AVCodecParserContext* codec_parser = av_parser_init(AV_CODEC_ID_H265);
47 if (codec_parser == nullptr) {
48 AERROR <<
"error: failed to init AVCodecParserContext";
49 return false;
50 }
51 AVPacket apt;
52 av_init_packet(&apt);
53 const std::unique_ptr<H265Decoder> decoder(new H265Decoder());
54 if (!decoder->Init()) {
55 AERROR <<
"error: failed to init decoder";
56 return false;
57 }
58 uint32_t local_size = static_cast<uint32_t>(input_video_buffer_.size());
59 uint8_t* local_data = const_cast<uint8_t*>(input_video_buffer_.data());
60 AINFO <<
"decoding: video size = " << local_size;
61 int frame_num = 0;
62 int warn_frame_num = 0;
63 std::vector<uint8_t> jpeg_buffer;
64 while (local_size > 0) {
65 int frame_len = av_parser_parse2(
66 codec_parser, decoder->GetCodecCtxH265(), &(apt.data), &(apt.size),
67 local_data, local_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
68 if (apt.data == nullptr) {
69 apt.data = local_data;
70 apt.size = local_size;
71 }
72 AINFO <<
"frame " << frame_num <<
": frame_len=" << frame_len
73 << ". left_size=" << local_size;
74 const auto decoding_result =
75 decoder->Process(apt.data, apt.size, &jpeg_buffer);
77
78
79 WriteOutputJpgFile(jpeg_buffer, GetOutputFile(frame_num));
80 ++frame_num;
81 } else {
82
83 ++warn_frame_num;
84 }
85 local_data += frame_len;
86 local_size -= frame_len;
87 }
88
89 for (int i = warn_frame_num; i > 0; --i) {
90
91 decoder->Process(nullptr, 0, &jpeg_buffer);
92 WriteOutputJpgFile(jpeg_buffer, GetOutputFile(frame_num));
93 AINFO <<
"frame " << frame_num <<
": read from buffer";
94 ++frame_num;
95 }
96 AINFO <<
"total frames: " << frame_num;
97 av_parser_close(codec_parser);
98 return true;
99}