mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Clarified & simplified ffmpeg decoding loop
This commit is contained in:
		| @@ -219,22 +219,21 @@ void CVideoInstance::prepareOutput(bool scaleToScreenSize, bool useTextureOutput | ||||
|  | ||||
| void FFMpegStream::decodeNextFrame() | ||||
| { | ||||
| 	AVPacket packet; | ||||
|  | ||||
| 	for(;;) | ||||
| 	{ | ||||
| 		int rc = avcodec_receive_frame(codecContext, frame); | ||||
| 		if(rc == AVERROR(EAGAIN)) | ||||
| 			break; | ||||
|  | ||||
| 		if(rc < 0) | ||||
| 			throwFFmpegError(rc); | ||||
| 	int rc = avcodec_receive_frame(codecContext, frame); | ||||
|  | ||||
| 	// frame extracted - data that was sent to codecContext before was sufficient | ||||
| 	if (rc == 0) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// returning AVERROR(EAGAIN) is legal - this indicates that codec requires more data from input stream to decode next frame | ||||
| 	if(rc != AVERROR(EAGAIN)) | ||||
| 		throwFFmpegError(rc); | ||||
|  | ||||
| 	for(;;) | ||||
| 	{ | ||||
| 		AVPacket packet; | ||||
|  | ||||
| 		// codecContext does not have enough input data - read next packet from input stream | ||||
| 		int ret = av_read_frame(formatContext, &packet); | ||||
| 		if(ret < 0) | ||||
| 		{ | ||||
| @@ -248,25 +247,33 @@ void FFMpegStream::decodeNextFrame() | ||||
| 			throwFFmpegError(ret); | ||||
| 		} | ||||
|  | ||||
| 		// Is this a packet from the video stream? | ||||
| 		// Is this a packet from the stream that needs decoding? | ||||
| 		if(packet.stream_index == streamIndex) | ||||
| 		{ | ||||
| 			// Decode video frame | ||||
| 			// Decode read packet | ||||
| 			// Note: this method may return AVERROR(EAGAIN). However this should never happen with ffmpeg API | ||||
| 			// since there is guaranteed call to avcodec_receive_frame and ffmpeg API promises that *both* of these methods will never return AVERROR(EAGAIN). | ||||
| 			int rc = avcodec_send_packet(codecContext, &packet); | ||||
| 			if(rc < 0 && rc != AVERROR(EAGAIN)) | ||||
| 			if(rc < 0) | ||||
| 				throwFFmpegError(rc); | ||||
|  | ||||
| 			rc = avcodec_receive_frame(codecContext, frame); | ||||
| 			if(rc == AVERROR(EAGAIN)) | ||||
| 			{ | ||||
| 				// still need more data - read next packet | ||||
| 				av_packet_unref(&packet); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if(rc < 0) | ||||
| 			else if(rc < 0) | ||||
| 			{ | ||||
| 				throwFFmpegError(rc); | ||||
|  | ||||
| 			av_packet_unref(&packet); | ||||
| 			return; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// read succesful. Exit the loop | ||||
| 				av_packet_unref(&packet); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		av_packet_unref(&packet); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user