/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocdecode/checkouts/docs-6.1.1/utils/video_demuxer.h Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocdecode/checkouts/docs-6.1.1/utils/video_demuxer.h Source File#

rocDecode: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocdecode/checkouts/docs-6.1.1/utils/video_demuxer.h Source File
video_demuxer.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22 
23 #pragma once
24 
25 #include <iostream>
26 extern "C" {
27  #include <libavcodec/avcodec.h>
28  #include <libavformat/avformat.h>
29  #if USE_AVCODEC_GREATER_THAN_58_134
30  #include <libavcodec/bsf.h>
31  #endif
32 }
33 
34 #include "rocdecode.h"
47 typedef enum SeekModeEnum {
48  SEEK_MODE_EXACT_FRAME = 0,
49  SEEK_MODE_PREV_KEY_FRAME = 1,
50  SEEK_MODE_NUM,
52 
57 typedef enum SeekCriteriaEnum {
58  SEEK_CRITERIA_FRAME_NUM = 0,
59  SEEK_CRITERIA_TIME_STAMP = 1,
60  SEEK_CRITERIA_NUM,
62 
63 struct PacketData {
64  int32_t key;
65  int64_t pts;
66  int64_t dts;
67  uint64_t pos;
68  uintptr_t bsl_data;
69  uint64_t bsl;
70  uint64_t duration;
71 };
72 
74 public:
76  : use_seek_(false), seek_frame_(0), seek_mode_(SEEK_MODE_PREV_KEY_FRAME), seek_crit_(SEEK_CRITERIA_FRAME_NUM),
77  out_frame_pts_(0), out_frame_duration_(0), num_frames_decoded_(0U) {}
78 
79  VideoSeekContext(uint64_t frame_id)
80  : use_seek_(true), seek_frame_(frame_id), seek_mode_(SEEK_MODE_PREV_KEY_FRAME),
81  seek_crit_(SEEK_CRITERIA_FRAME_NUM), out_frame_pts_(0), out_frame_duration_(0), num_frames_decoded_(0U) {}
82 
83  VideoSeekContext& operator=(const VideoSeekContext& other) {
84  use_seek_ = other.use_seek_;
85  seek_frame_ = other.seek_frame_;
86  seek_mode_ = other.seek_mode_;
87  seek_crit_ = other.seek_crit_;
88  out_frame_pts_ = other.out_frame_pts_;
89  out_frame_duration_ = other.out_frame_duration_;
90  num_frames_decoded_ = other.num_frames_decoded_;
91  return *this;
92  }
93 
94  /* Will be set to false when not seeking, true otherwise;
95  */
96  bool use_seek_;
97 
98  /* Frame we want to get. Set by user.
99  * Shall be set to frame timestamp in case seek is done by time.
100  */
101  uint64_t seek_frame_;
102 
103  /* Mode in which we seek. */
104  SeekMode seek_mode_;
105 
106  /* Criteria by which we seek. */
107  SeekCriteria seek_crit_;
108 
109  /* PTS of frame found after seek. */
110  int64_t out_frame_pts_;
111 
112  /* Duration of frame found after seek. */
113  int64_t out_frame_duration_;
114 
115  /* Number of frames that were decoded during seek. */
116  uint64_t num_frames_decoded_;
117 
118 };
119 
120 
121 // Video Demuxer Interface class
123  public:
125  public:
126  virtual ~StreamProvider() {}
127  virtual int GetData(uint8_t *buf, int buf_size) = 0;
128  };
129  AVCodecID GetCodecID() { return av_video_codec_id_; };
130  VideoDemuxer(const char *input_file_path) : VideoDemuxer(CreateFmtContextUtil(input_file_path)) {}
131  VideoDemuxer(StreamProvider *stream_provider) : VideoDemuxer(CreateFmtContextUtil(stream_provider)) {av_io_ctx_ = av_fmt_input_ctx_->pb;}
132  ~VideoDemuxer();
133  bool Demux(uint8_t **video, int *video_size, int64_t *pts = nullptr);
134  bool Seek(VideoSeekContext& seek_ctx, uint8_t** pp_video, int* video_size);
135  const uint32_t GetWidth() const { return width_;}
136  const uint32_t GetHeight() const { return height_;}
137  const uint32_t GetChromaHeight() const { return chroma_height_;}
138  const uint32_t GetBitDepth() const { return bit_depth_;}
139  const uint32_t GetBytePerPixel() const { return byte_per_pixel_;}
140  const uint32_t GetBitRate() const { return bit_rate_;}
141  const double GetFrameRate() const {return frame_rate_;};
142  bool IsVFR() const { return frame_rate_ != avg_frame_rate_; };
143  int64_t TsFromTime(double ts_sec) {
144  // Convert integer timestamp representation to AV_TIME_BASE and switch to fixed_point
145  auto const ts_tbu = llround(ts_sec * AV_TIME_BASE);
146 
147  // Rescale the timestamp to value represented in stream base units;
148  AVRational time_factor = {1, AV_TIME_BASE};
149  return av_rescale_q(ts_tbu, time_factor, av_fmt_input_ctx_->streams[av_stream_]->time_base);
150  }
151 
152  int64_t TsFromFrameNumber(int64_t frame_num) {
153  auto const ts_sec = static_cast<double>(frame_num) / frame_rate_;
154  return TsFromTime(ts_sec);
155  }
156 
157  private:
158  VideoDemuxer(AVFormatContext *av_fmt_input_ctx);
159  AVFormatContext *CreateFmtContextUtil(StreamProvider *stream_provider);
160  AVFormatContext *CreateFmtContextUtil(const char *input_file_path);
161  static int ReadPacket(void *data, uint8_t *buf, int buf_size);
162  AVFormatContext *av_fmt_input_ctx_ = nullptr;
163  AVIOContext *av_io_ctx_ = nullptr;
164  AVPacket* packet_ = nullptr;
165  AVPacket* packet_filtered_ = nullptr;
166  AVBSFContext *av_bsf_ctx_ = nullptr;
167  AVCodecID av_video_codec_id_;
168  AVPixelFormat chroma_format_;
169  double frame_rate_ = 0.0;
170  double avg_frame_rate_ = 0.0;
171  uint8_t *data_with_header_ = nullptr;
172  int av_stream_ = 0;
173  bool is_h264_ = false;
174  bool is_hevc_ = false;
175  bool is_mpeg4_ = false;
176  bool is_seekable_ = false;
177  int64_t default_time_scale_ = 1000;
178  double time_base_ = 0.0;
179  uint32_t frame_count_ = 0;
180  uint32_t width_ = 0;
181  uint32_t height_ = 0;
182  uint32_t chroma_height_ = 0;
183  uint32_t bit_depth_ = 0;
184  uint32_t byte_per_pixel_ = 0;
185  uint32_t bit_rate_ = 0;
186 };
187 
188 VideoDemuxer::~VideoDemuxer() {
189  if (!av_fmt_input_ctx_) {
190  return;
191  }
192  if (packet_) {
193  av_packet_free(&packet_);
194  }
195  if (packet_filtered_) {
196  av_packet_free(&packet_filtered_);
197  }
198  if (av_bsf_ctx_) {
199  av_bsf_free(&av_bsf_ctx_);
200  }
201  avformat_close_input(&av_fmt_input_ctx_);
202  if (av_io_ctx_) {
203  av_freep(&av_io_ctx_->buffer);
204  av_freep(&av_io_ctx_);
205  }
206  if (data_with_header_) {
207  av_free(data_with_header_);
208  }
209 }
210 
211 bool VideoDemuxer::Demux(uint8_t **video, int *video_size, int64_t *pts) {
212  if (!av_fmt_input_ctx_) {
213  return false;
214  }
215  *video_size = 0;
216  if (packet_->data) {
217  av_packet_unref(packet_);
218  }
219  int ret = 0;
220  while ((ret = av_read_frame(av_fmt_input_ctx_, packet_)) >= 0 && packet_->stream_index != av_stream_) {
221  av_packet_unref(packet_);
222  }
223  if (ret < 0) {
224  return false;
225  }
226  if (is_h264_ || is_hevc_) {
227  if (packet_filtered_->data) {
228  av_packet_unref(packet_filtered_);
229  }
230  if (av_bsf_send_packet(av_bsf_ctx_, packet_) != 0) {
231  std::cerr << "ERROR: av_bsf_send_packet failed!" << std::endl;
232  return false;
233  }
234  if (av_bsf_receive_packet(av_bsf_ctx_, packet_filtered_) != 0) {
235  std::cerr << "ERROR: av_bsf_receive_packet failed!" << std::endl;
236  return false;
237  }
238  *video = packet_filtered_->data;
239  *video_size = packet_filtered_->size;
240  if (pts)
241  *pts = (int64_t) (packet_filtered_->pts * default_time_scale_ * time_base_);
242  } else {
243  if (is_mpeg4_ && (frame_count_ == 0)) {
244  int ext_data_size = av_fmt_input_ctx_->streams[av_stream_]->codecpar->extradata_size;
245  if (ext_data_size > 0) {
246  data_with_header_ = (uint8_t *)av_malloc(ext_data_size + packet_->size - 3 * sizeof(uint8_t));
247  if (!data_with_header_) {
248  std::cerr << "ERROR: av_malloc failed!" << std::endl;
249  return false;
250  }
251  memcpy(data_with_header_, av_fmt_input_ctx_->streams[av_stream_]->codecpar->extradata, ext_data_size);
252  memcpy(data_with_header_ + ext_data_size, packet_->data + 3, packet_->size - 3 * sizeof(uint8_t));
253  *video = data_with_header_;
254  *video_size = ext_data_size + packet_->size - 3 * sizeof(uint8_t);
255  }
256  } else {
257  *video = packet_->data;
258  *video_size = packet_->size;
259  }
260  if (pts)
261  *pts = (int64_t)(packet_->pts * default_time_scale_ * time_base_);
262  }
263  frame_count_++;
264  return true;
265 }
266 
267 VideoDemuxer::VideoDemuxer(AVFormatContext *av_fmt_input_ctx) : av_fmt_input_ctx_(av_fmt_input_ctx) {
268  av_log_set_level(AV_LOG_QUIET);
269  if (!av_fmt_input_ctx_) {
270  std::cerr << "ERROR: av_fmt_input_ctx_ is not vaild!" << std::endl;
271  return;
272  }
273  packet_ = av_packet_alloc();
274  packet_filtered_ = av_packet_alloc();
275  if (!packet_ || !packet_filtered_) {
276  std::cerr << "ERROR: av_packet_alloc failed!" << std::endl;
277  return;
278  }
279  if (avformat_find_stream_info(av_fmt_input_ctx_, nullptr) < 0) {
280  std::cerr << "ERROR: avformat_find_stream_info failed!" << std::endl;
281  return;
282  }
283  av_stream_ = av_find_best_stream(av_fmt_input_ctx_, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
284  if (av_stream_ < 0) {
285  std::cerr << "ERROR: av_find_best_stream failed!" << std::endl;
286  av_packet_free(&packet_);
287  av_packet_free(&packet_filtered_);
288  return;
289  }
290  av_video_codec_id_ = av_fmt_input_ctx_->streams[av_stream_]->codecpar->codec_id;
291  width_ = av_fmt_input_ctx_->streams[av_stream_]->codecpar->width;
292  height_ = av_fmt_input_ctx_->streams[av_stream_]->codecpar->height;
293  chroma_format_ = (AVPixelFormat)av_fmt_input_ctx_->streams[av_stream_]->codecpar->format;
294  bit_rate_ = av_fmt_input_ctx_->streams[av_stream_]->codecpar->bit_rate;
295  if (av_fmt_input_ctx_->streams[av_stream_]->r_frame_rate.den != 0)
296  frame_rate_ = static_cast<double>(av_fmt_input_ctx_->streams[av_stream_]->r_frame_rate.num) / static_cast<double>(av_fmt_input_ctx_->streams[av_stream_]->r_frame_rate.den);
297  if (av_fmt_input_ctx_->streams[av_stream_]->avg_frame_rate.den != 0)
298  avg_frame_rate_ = static_cast<double>(av_fmt_input_ctx_->streams[av_stream_]->avg_frame_rate.num) / static_cast<double>(av_fmt_input_ctx_->streams[av_stream_]->avg_frame_rate.den);
299 
300  switch (chroma_format_) {
301  case AV_PIX_FMT_YUV420P10LE:
302  case AV_PIX_FMT_GRAY10LE:
303  bit_depth_ = 10;
304  chroma_height_ = (height_ + 1) >> 1;
305  byte_per_pixel_ = 2;
306  break;
307  case AV_PIX_FMT_YUV420P12LE:
308  bit_depth_ = 12;
309  chroma_height_ = (height_ + 1) >> 1;
310  byte_per_pixel_ = 2;
311  break;
312  case AV_PIX_FMT_YUV444P10LE:
313  bit_depth_ = 10;
314  chroma_height_ = height_ << 1;
315  byte_per_pixel_ = 2;
316  break;
317  case AV_PIX_FMT_YUV444P12LE:
318  bit_depth_ = 12;
319  chroma_height_ = height_ << 1;
320  byte_per_pixel_ = 2;
321  break;
322  case AV_PIX_FMT_YUV444P:
323  bit_depth_ = 8;
324  chroma_height_ = height_ << 1;
325  byte_per_pixel_ = 1;
326  break;
327  case AV_PIX_FMT_YUV420P:
328  case AV_PIX_FMT_YUVJ420P:
329  case AV_PIX_FMT_YUVJ422P:
330  case AV_PIX_FMT_YUVJ444P:
331  case AV_PIX_FMT_GRAY8:
332  bit_depth_ = 8;
333  chroma_height_ = (height_ + 1) >> 1;
334  byte_per_pixel_ = 1;
335  break;
336  default:
337  chroma_format_ = AV_PIX_FMT_YUV420P;
338  bit_depth_ = 8;
339  chroma_height_ = (height_ + 1) >> 1;
340  byte_per_pixel_ = 1;
341  }
342 
343  AVRational time_base = av_fmt_input_ctx_->streams[av_stream_]->time_base;
344  time_base_ = av_q2d(time_base);
345 
346  is_h264_ = av_video_codec_id_ == AV_CODEC_ID_H264 && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
347  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
348  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
349  is_hevc_ = av_video_codec_id_ == AV_CODEC_ID_HEVC && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
350  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
351  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
352  is_mpeg4_ = av_video_codec_id_ == AV_CODEC_ID_MPEG4 && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
353  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
354  || !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
355 
356  // Check if the input file allow seek functionality.
357  is_seekable_ = av_fmt_input_ctx_->iformat->read_seek || av_fmt_input_ctx_->iformat->read_seek2;
358 
359  if (is_h264_) {
360  const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
361  if (!bsf) {
362  std::cerr << "ERROR: av_bsf_get_by_name() failed" << std::endl;
363  av_packet_free(&packet_);
364  av_packet_free(&packet_filtered_);
365  return;
366  }
367  if (av_bsf_alloc(bsf, &av_bsf_ctx_) != 0) {
368  std::cerr << "ERROR: av_bsf_alloc failed!" << std::endl;
369  return;
370  }
371  avcodec_parameters_copy(av_bsf_ctx_->par_in, av_fmt_input_ctx_->streams[av_stream_]->codecpar);
372  if (av_bsf_init(av_bsf_ctx_) < 0) {
373  std::cerr << "ERROR: av_bsf_init failed!" << std::endl;
374  return;
375  }
376  }
377  if (is_hevc_) {
378  const AVBitStreamFilter *bsf = av_bsf_get_by_name("hevc_mp4toannexb");
379  if (!bsf) {
380  std::cerr << "ERROR: av_bsf_get_by_name() failed" << std::endl;
381  av_packet_free(&packet_);
382  av_packet_free(&packet_filtered_);
383  return;
384  }
385  if (av_bsf_alloc(bsf, &av_bsf_ctx_) != 0 ) {
386  std::cerr << "ERROR: av_bsf_alloc failed!" << std::endl;
387  return;
388  }
389  avcodec_parameters_copy(av_bsf_ctx_->par_in, av_fmt_input_ctx_->streams[av_stream_]->codecpar);
390  if (av_bsf_init(av_bsf_ctx_) < 0) {
391  std::cerr << "ERROR: av_bsf_init failed!" << std::endl;
392  return;
393  }
394  }
395 }
396 
397 bool VideoDemuxer::Seek(VideoSeekContext& seek_ctx, uint8_t** pp_video, int* video_size) {
398  /* !!! IMPORTANT !!!
399  * Across this function, packet decode timestamp (DTS) values are used to
400  * compare given timestamp against. This is done because DTS values shall
401  * monotonically increase during the course of decoding unlike PTS values
402  * which may be affected by frame reordering due to B frames.
403  */
404 
405  if (!is_seekable_) {
406  std::cerr << "ERROR: Seek isn't supported for this input." << std::endl;
407  return false;
408  }
409 
410  if (IsVFR() && (SEEK_CRITERIA_FRAME_NUM == seek_ctx.seek_crit_)) {
411  std::cerr << "ERROR: Can't seek by frame number in VFR sequences. Seek by timestamp instead." << std::endl;
412  return false;
413  }
414 
415  // Seek for single frame;
416  auto seek_frame = [&](VideoSeekContext const& seek_ctx, int flags) {
417  bool seek_backward = true;
418  int64_t timestamp = 0;
419  int ret = 0;
420 
421  switch (seek_ctx.seek_crit_) {
422  case SEEK_CRITERIA_FRAME_NUM:
423  timestamp = TsFromFrameNumber(seek_ctx.seek_frame_);
424  ret = av_seek_frame(av_fmt_input_ctx_, av_stream_, timestamp, seek_backward ? AVSEEK_FLAG_BACKWARD | flags : flags);
425  break;
426  case SEEK_CRITERIA_TIME_STAMP:
427  timestamp = TsFromTime(seek_ctx.seek_frame_);
428  ret = av_seek_frame(av_fmt_input_ctx_, av_stream_, timestamp, seek_backward ? AVSEEK_FLAG_BACKWARD | flags : flags);
429  break;
430  default:
431  std::cerr << "ERROR: Invalid seek mode" << std::endl;
432  ret = -1;
433  }
434 
435  if (ret < 0) {
436  throw std::runtime_error("ERROR: seeking for frame: ");
437  }
438  };
439 
440  // Check if frame satisfies seek conditions;
441  auto is_seek_done = [&](PacketData& pkt_data, VideoSeekContext const& seek_ctx) {
442  int64_t target_ts = 0;
443 
444  switch (seek_ctx.seek_crit_) {
445  case SEEK_CRITERIA_FRAME_NUM:
446  target_ts = TsFromFrameNumber(seek_ctx.seek_frame_);
447  break;
448  case SEEK_CRITERIA_TIME_STAMP:
449  target_ts = TsFromTime(seek_ctx.seek_frame_);
450  break;
451  default:
452  std::cerr << "ERROR::Invalid seek criteria" << std::endl;
453  return -1;
454  }
455 
456  if (pkt_data.dts == target_ts) {
457  return 0;
458  }
459  else if (pkt_data.dts > target_ts) {
460  return 1;
461  }
462  else {
463  return -1;
464  };
465  };
466 
467  /* This will seek for exact frame number;
468  * Note that decoder may not be able to decode such frame; */
469  auto seek_for_exact_frame = [&](PacketData& pkt_data, VideoSeekContext& seek_ctx) {
470  // Repetititive seek until seek condition is satisfied;
471  VideoSeekContext tmp_ctx(seek_ctx.seek_frame_);
472  seek_frame(tmp_ctx, AVSEEK_FLAG_ANY);
473 
474  int seek_done = 0;
475  do {
476  if (!Demux(pp_video, video_size)) {
477  break;
478  }
479  seek_done = is_seek_done(pkt_data, seek_ctx);
480 
481  // We've gone too far and need to seek backwards;
482  if (seek_done > 0) {
483  tmp_ctx.seek_frame_--;
484  seek_frame(tmp_ctx, AVSEEK_FLAG_ANY);
485  }
486  // Need to read more frames until we reach requested number;
487  else if (seek_done < 0) {
488  continue;
489  }
490  } while (seek_done != 0);
491 
492  seek_ctx.out_frame_pts_ = pkt_data.pts;
493  seek_ctx.out_frame_duration_ = pkt_data.duration;
494  };
495 
496  // Seek for closest key frame in the past;
497  auto seek_for_prev_key_frame = [&](PacketData& pkt_data, VideoSeekContext& seek_ctx) {
498  seek_frame(seek_ctx.seek_crit_, AVSEEK_FLAG_BACKWARD);
499  Demux(pp_video, video_size);
500  seek_ctx.out_frame_pts_ = pkt_data.pts;
501  seek_ctx.out_frame_duration_ = pkt_data.duration;
502  };
503 
504  PacketData pktData;
505  pktData.bsl_data = size_t(*pp_video);
506  pktData.bsl = *video_size;
507 
508  switch (seek_ctx.seek_mode_) {
509  case SEEK_MODE_EXACT_FRAME:
510  seek_for_exact_frame(pktData, seek_ctx);
511  break;
512  case SEEK_MODE_PREV_KEY_FRAME:
513  seek_for_prev_key_frame(pktData, seek_ctx);
514  break;
515  default:
516  throw std::runtime_error("ERROR::Unsupported seek mode");
517  break;
518  }
519 
520  return true;
521 }
522 
523 AVFormatContext *VideoDemuxer::CreateFmtContextUtil(StreamProvider *stream_provider) {
524  AVFormatContext *ctx = nullptr;
525  if (!(ctx = avformat_alloc_context())) {
526  std::cerr << "ERROR: avformat_alloc_context failed" << std::endl;
527  return nullptr;
528  }
529  uint8_t *avioc_buffer = nullptr;
530  int avioc_buffer_size = 100 * 1024 * 1024;
531  avioc_buffer = (uint8_t *)av_malloc(avioc_buffer_size);
532  if (!avioc_buffer) {
533  std::cerr << "ERROR: av_malloc failed!" << std::endl;
534  return nullptr;
535  }
536  av_io_ctx_ = avio_alloc_context(avioc_buffer, avioc_buffer_size,
537  0, stream_provider, &ReadPacket, nullptr, nullptr);
538  if (!av_io_ctx_) {
539  std::cerr << "ERROR: avio_alloc_context failed!" << std::endl;
540  return nullptr;
541  }
542  ctx->pb = av_io_ctx_;
543 
544  if (avformat_open_input(&ctx, nullptr, nullptr, nullptr) != 0) {
545  std::cerr << "ERROR: avformat_open_input failed!" << std::endl;
546  return nullptr;
547  }
548  return ctx;
549 }
550 
551 AVFormatContext *VideoDemuxer::CreateFmtContextUtil(const char *input_file_path) {
552  avformat_network_init();
553  AVFormatContext *ctx = nullptr;
554  if (avformat_open_input(&ctx, input_file_path, nullptr, nullptr) != 0 ) {
555  std::cerr << "ERROR: avformat_open_input failed!" << std::endl;
556  return nullptr;
557  }
558  return ctx;
559 }
560 
561 int VideoDemuxer::ReadPacket(void *data, uint8_t *buf, int buf_size) {
562  return ((StreamProvider *)data)->GetData(buf, buf_size);
563 }
564 
565 static inline rocDecVideoCodec AVCodec2RocDecVideoCodec(AVCodecID av_codec) {
566  switch (av_codec) {
567  case AV_CODEC_ID_MPEG1VIDEO : return rocDecVideoCodec_MPEG1;
568  case AV_CODEC_ID_MPEG2VIDEO : return rocDecVideoCodec_MPEG2;
569  case AV_CODEC_ID_MPEG4 : return rocDecVideoCodec_MPEG4;
570  case AV_CODEC_ID_H264 : return rocDecVideoCodec_AVC;
571  case AV_CODEC_ID_HEVC : return rocDecVideoCodec_HEVC;
572  case AV_CODEC_ID_VP8 : return rocDecVideoCodec_VP8;
573  case AV_CODEC_ID_VP9 : return rocDecVideoCodec_VP9;
574  case AV_CODEC_ID_MJPEG : return rocDecVideoCodec_JPEG;
575  case AV_CODEC_ID_AV1 : return rocDecVideoCodec_AV1;
576  default : return rocDecVideoCodec_NumCodecs;
577  }
578 }
Definition: video_demuxer.h:124
Definition: video_demuxer.h:122
Definition: video_demuxer.h:73
The AMD rocDecode Library.
@ rocDecVideoCodec_AV1
Definition: rocdecode.h:84
@ rocDecVideoCodec_MPEG4
Definition: rocdecode.h:81
@ rocDecVideoCodec_HEVC
Definition: rocdecode.h:83
@ rocDecVideoCodec_MPEG1
Definition: rocdecode.h:79
@ rocDecVideoCodec_JPEG
Definition: rocdecode.h:87
@ rocDecVideoCodec_VP9
Definition: rocdecode.h:86
@ rocDecVideoCodec_AVC
Definition: rocdecode.h:82
@ rocDecVideoCodec_MPEG2
Definition: rocdecode.h:80
@ rocDecVideoCodec_VP8
Definition: rocdecode.h:85
@ rocDecVideoCodec_NumCodecs
Definition: rocdecode.h:88
Definition: video_demuxer.h:63
SeekModeEnum
Enum for Seek mode.
Definition: video_demuxer.h:47
enum SeekModeEnum SeekMode
Enum for Seek mode.
SeekCriteriaEnum
Enum for Seek Criteria.
Definition: video_demuxer.h:57
enum SeekCriteriaEnum SeekCriteria
Enum for Seek Criteria.