|
1 | 1 | #include "MediaDecoder.hpp"
|
2 | 2 |
|
| 3 | +#include <cassert> |
| 4 | + |
3 | 5 | void
|
4 | 6 | MediaDecoder::initFfmpeg()
|
5 | 7 | {
|
@@ -68,18 +70,18 @@ MediaDecoder::openFile(const char* filename)
|
68 | 70 | for (int i = 0; i < streamCount; ++i) {
|
69 | 71 | if (0 > (intRet = this->prepareStream(i))) {
|
70 | 72 | this->outputMessage(0, "prepareStream() failed: ret=%d", intRet);
|
71 |
| - return intRet; |
72 | 73 | }
|
73 | 74 | if (mFirstVideoStreamIndex == -1 && mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
74 | 75 | mFirstVideoStreamIndex = i;
|
75 | 76 | }
|
76 | 77 | }
|
77 | 78 |
|
78 |
| - if (mFirstVideoStreamIndex != -1) { |
79 |
| - AVCodecContext* codecContext = mFormatContext->streams[mFirstVideoStreamIndex]->codec; |
80 |
| - this->setScaleParameters(codecContext->width, codecContext->height, PIX_FMT_RGB32, Stride_4bytes); |
81 |
| - } |
82 |
| - |
| 79 | + if (mFirstVideoStreamIndex != -1) { |
| 80 | + this->outputMessage(0, "Video stream is %d", mFirstVideoStreamIndex); |
| 81 | + AVCodecContext* codecContext = mFormatContext->streams[mFirstVideoStreamIndex]->codec; |
| 82 | + this->setScaleParameters(codecContext->width, codecContext->height, PIX_FMT_RGB32, Stride_4bytes); |
| 83 | + } |
| 84 | + |
83 | 85 | return 0;
|
84 | 86 | }
|
85 | 87 |
|
@@ -117,6 +119,7 @@ MediaDecoder::setScaleParameters(int width, int height, PixelFormat pixelFormat,
|
117 | 119 | // SWS_BILINEAR,
|
118 | 120 | SWS_FAST_BILINEAR,
|
119 | 121 | NULL, NULL, NULL);
|
| 122 | + |
120 | 123 | if (!mSwsContext) {
|
121 | 124 | this->outputMessage(0, "sws_getContext failed.");
|
122 | 125 | return -1;
|
@@ -147,32 +150,32 @@ MediaDecoder::setScaleParameters(int width, int height, PixelFormat pixelFormat,
|
147 | 150 | return 0;
|
148 | 151 | }
|
149 | 152 |
|
| 153 | +int |
| 154 | +MediaDecoder::seek(int streamIndex, int64_t timestamp) |
| 155 | +{ |
| 156 | + return av_seek_frame(mFormatContext, streamIndex, timestamp, 0); |
| 157 | +} |
| 158 | + |
150 | 159 | int
|
151 | 160 | MediaDecoder::seek(double timestamp)
|
152 | 161 | {
|
153 |
| - int intRet; |
154 |
| - int streamCount = this->getStreamCount(); |
155 |
| - int failCount = 0; |
156 |
| - for (int i = 0; i < streamCount; ++i) { |
157 |
| - double timeBase = av_q2d(mFormatContext->streams[i]->time_base); |
158 |
| - int64_t ts = static_cast<int64_t>(timestamp / timeBase); |
159 |
| - intRet = av_seek_frame(mFormatContext, i, ts, 0); |
160 |
| - if (0 > intRet) { |
161 |
| - failCount ++; |
162 |
| - } |
163 |
| - } |
164 |
| - return failCount; |
| 162 | + return this->seek(-1, static_cast<uint64_t>(timestamp * AV_TIME_BASE)); |
165 | 163 | }
|
166 | 164 |
|
167 | 165 | int
|
168 | 166 | MediaDecoder::seekToIndex(int streamIndex, int index) {
|
169 | 167 | AVStream* stream = this->getStream(streamIndex);
|
170 |
| - if (!stream) { return -1; } |
| 168 | + if (!stream) { |
| 169 | + this->outputMessage(0, "Stream index %d not found.", streamIndex); |
| 170 | + return -1; } |
171 | 171 |
|
172 | 172 | AVIndexEntry* entries = stream->index_entries;
|
173 |
| - if (!entries) { return -1; } |
| 173 | + if (!entries) { |
| 174 | + this->outputMessage(0, "Tried to seek by index, but there is no index entries."); |
| 175 | + return -1; } |
174 | 176 |
|
175 |
| - if (0 < index || index <= stream->nb_index_entries) { |
| 177 | + if (index < 0 || stream->nb_index_entries <= index) { |
| 178 | + this->outputMessage(0, "Index out of bound: %d / %d", index, stream->nb_index_entries); |
176 | 179 | return -1;
|
177 | 180 | }
|
178 | 181 |
|
@@ -234,6 +237,10 @@ MediaDecoder::decodeVideoFrame(AVPacket* packet, AVFrame* outFrame, double* outT
|
234 | 237 | int
|
235 | 238 | MediaDecoder::scaleVideoFrame(AVFrame* frame, uint8_t* buffer, int bufferSize)
|
236 | 239 | {
|
| 240 | + if (!mSwsContext) { |
| 241 | + this->outputMessage(0, "sws context is not initialized."); |
| 242 | + return -1; } |
| 243 | + |
237 | 244 | int intRet;
|
238 | 245 | uint8_t* data[] = { (uint8_t*)buffer, NULL, NULL, NULL };
|
239 | 246 | int lineSize[] = { mScaleStride, 0, 0, 0 };
|
@@ -279,7 +286,6 @@ MediaDecoder::decodeVideo(AVPacket* packet, uint8_t* buffer, int bufferSize, dou
|
279 | 286 | goto CLEANUP;
|
280 | 287 | }
|
281 | 288 |
|
282 |
| - |
283 | 289 | // scale and transform
|
284 | 290 | intRet = this->scaleVideoFrame(mFrame, buffer, bufferSize);
|
285 | 291 | if (intRet < 0) {
|
@@ -343,9 +349,9 @@ MediaDecoder::prepareStream(int streamIndex)
|
343 | 349 | AVStream* stream = mFormatContext->streams[streamIndex];
|
344 | 350 | AVCodecContext* codecContext = stream->codec;
|
345 | 351 | AVCodec* codec = avcodec_find_decoder(codecContext->codec_id);
|
346 |
| - |
| 352 | + |
347 | 353 | if (!codec) {
|
348 |
| - this->outputMessage(0, "Failed to find decoder: codec_id=%d", codecContext->codec_id); |
| 354 | + this->outputMessage(0, "Failed to find decoder: streamIndex=%d codecId=%d codecType=%d", streamIndex, codecContext->codec_id, codecContext->codec_type); |
349 | 355 | return -1;
|
350 | 356 | }
|
351 | 357 |
|
|
0 commit comments