@@ -40,11 +40,6 @@ int64_t secondsToClosestPts(double seconds, const AVRational& timeBase) {
4040 return static_cast <int64_t >(std::round (seconds * timeBase.den ));
4141}
4242
43- struct AVInput {
44- UniqueAVFormatContext formatContext;
45- std::unique_ptr<AVIOBytesContext> ioBytesContext;
46- };
47-
4843std::vector<std::string> splitStringWithDelimiters (
4944 const std::string& str,
5045 const std::string& delims) {
@@ -72,50 +67,47 @@ VideoDecoder::VideoDecoder(const std::string& videoFilePath, SeekMode seekMode)
7267 : seekMode_(seekMode) {
7368 av_log_set_level (AV_LOG_QUIET);
7469
75- AVFormatContext* formatContext = nullptr ;
76- int open_ret = avformat_open_input (
77- &formatContext, videoFilePath.c_str (), nullptr , nullptr );
78- if (open_ret != 0 ) {
79- throw std::invalid_argument (
80- " Could not open input file: " + videoFilePath + " " +
81- getFFMPEGErrorStringFromErrorCode (open_ret));
82- }
83- TORCH_CHECK (formatContext != nullptr );
84- AVInput input;
85- input.formatContext .reset (formatContext);
86- formatContext_ = std::move (input.formatContext );
70+ AVFormatContext* rawContext = nullptr ;
71+ int ffmpegStatus =
72+ avformat_open_input (&rawContext, videoFilePath.c_str (), nullptr , nullptr );
73+ TORCH_CHECK (
74+ ffmpegStatus == 0 ,
75+ " Could not open input file: " + videoFilePath + " " +
76+ getFFMPEGErrorStringFromErrorCode (ffmpegStatus));
77+ TORCH_CHECK (rawContext != nullptr );
78+ formatContext_.reset (rawContext);
8779
8880 initializeDecoder ();
8981}
9082
91- VideoDecoder::VideoDecoder (const void * buffer , size_t length, SeekMode seekMode)
83+ VideoDecoder::VideoDecoder (const void * data , size_t length, SeekMode seekMode)
9284 : seekMode_(seekMode) {
93- TORCH_CHECK (buffer != nullptr , " Video buffer cannot be nullptr!" );
85+ TORCH_CHECK (data != nullptr , " Video data buffer cannot be nullptr!" );
9486
9587 av_log_set_level (AV_LOG_QUIET);
9688
97- AVInput input ;
98- input. formatContext . reset (avformat_alloc_context ( ));
99- TORCH_CHECK (
100- input. formatContext . get () != nullptr , " Unable to alloc avformat context " );
101- constexpr int kAVIOInternalTemporaryBufferSize = 64 * 1024 ;
102- input. ioBytesContext . reset (
103- new AVIOBytesContext (buffer, length, kAVIOInternalTemporaryBufferSize ));
104- if (!input. ioBytesContext ) {
105- throw std::runtime_error ( " Failed to create AVIOBytesContext " );
106- }
107- input. formatContext ->pb = input. ioBytesContext ->getAVIO ();
108- AVFormatContext* tempFormatContext = input. formatContext . release ();
109- int open_ret =
110- avformat_open_input (&tempFormatContext, nullptr , nullptr , nullptr );
111- input. formatContext . reset (tempFormatContext );
112- if (open_ret != 0 ) {
113- throw std::runtime_error (
114- std::string ( " Failed to open input buffer: " ) +
115- getFFMPEGErrorStringFromErrorCode (open_ret ));
89+ constexpr int bufferSize = 64 * 1024 ;
90+ ioBytesContext_. reset (new AVIOBytesContext (data, length, bufferSize ));
91+ TORCH_CHECK (ioBytesContext_, " Failed to create AVIOBytesContext " );
92+
93+ // Because FFmpeg requires a reference to a pointer in the call to open, we
94+ // can't use a unique pointer here. Note that means we must call free if open
95+ // fails.
96+ AVFormatContext* rawContext = avformat_alloc_context ();
97+ TORCH_CHECK (rawContext != nullptr , " Unable to alloc avformat context " );
98+
99+ rawContext ->pb = ioBytesContext_ ->getAVIO ();
100+ int ffmpegStatus =
101+ avformat_open_input (&rawContext, nullptr , nullptr , nullptr );
102+ if (ffmpegStatus != 0 ) {
103+ avformat_free_context (rawContext );
104+ TORCH_CHECK (
105+ false ,
106+ " Failed to open input buffer: " +
107+ getFFMPEGErrorStringFromErrorCode (ffmpegStatus ));
116108 }
117- formatContext_ = std::move (input. formatContext );
118- ioBytesContext_ = std::move (input. ioBytesContext );
109+
110+ formatContext_. reset (rawContext );
119111
120112 initializeDecoder ();
121113}
0 commit comments