Jelajahi Sumber

CVideoHandler: use new ffmpeg

Konstantin 3 tahun lalu
induk
melakukan
e7b753c222
2 mengubah file dengan 36 tambahan dan 25 penghapusan
  1. 33 24
      client/CVideoHandler.cpp
  2. 3 1
      client/CVideoHandler.h

+ 33 - 24
client/CVideoHandler.cpp

@@ -72,11 +72,6 @@ CVideoPlayer::CVideoPlayer()
 	refreshWait = 0;
 	refreshCount = 0;
 	doLoop = false;
-
-	// Register codecs. TODO: May be overkill. Should call a
-	// combination of av_register_input_format() /
-	// av_register_output_format() / av_register_protocol() instead.
-	av_register_all();
 }
 
 bool CVideoPlayer::open(std::string fname, bool scale)
@@ -127,7 +122,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
 	stream = -1;
 	for(ui32 i=0; i<format->nb_streams; i++)
 	{
-		if (format->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
+		if (format->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 		{
 			stream = i;
 			break;
@@ -138,11 +133,8 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
 		// No video stream in that file
 		return false;
 
-	// Get a pointer to the codec context for the video stream
-	codecContext = format->streams[stream]->codec;
-
 	// Find the decoder for the video stream
-	codec = avcodec_find_decoder(codecContext->codec_id);
+	codec = avcodec_find_decoder(format->streams[stream]->codecpar->codec_id);
 
 	if (codec == nullptr)
 	{
@@ -150,6 +142,15 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
 		return false;
 	}
 
+	codecContext = avcodec_alloc_context3(codec);
+	// Get a pointer to the codec context for the video stream
+	int ret = avcodec_parameters_to_context(codecContext, format->streams[stream]->codecpar);
+	if (ret < 0)
+	{
+		//We cannot get codec from parameters
+		return false;
+	}
+
 	// Open codec
 	if ( avcodec_open2(codecContext, codec, nullptr) < 0 )
 	{
@@ -266,24 +267,28 @@ bool CVideoPlayer::nextFrame()
 			if (packet.stream_index == stream)
 			{
 				// Decode video frame
-
-				avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);
-
+				int rc = avcodec_send_packet(codecContext, &packet);
+				if (rc >=0)
+					packet.size = 0;
+				rc = avcodec_receive_frame(codecContext, frame);
+				if (rc >= 0)
+					frameFinished = 1;
 				// Did we get a video frame?
 				if (frameFinished)
 				{
-					AVPicture pict;
+					uint8_t *data[4];
+					int linesize[4];
 
 					if (texture) {
-						avpicture_alloc(&pict, AV_PIX_FMT_YUV420P, pos.w, pos.h);
+						av_image_alloc(data, linesize, pos.w, pos.h, AV_PIX_FMT_YUV420P, 1);
 
 						sws_scale(sws, frame->data, frame->linesize,
-								  0, codecContext->height, pict.data, pict.linesize);
+								  0, codecContext->height, data, linesize);
 
-						SDL_UpdateYUVTexture(texture, NULL, pict.data[0], pict.linesize[0],
-								pict.data[1], pict.linesize[1],
-								pict.data[2], pict.linesize[2]);
-						avpicture_free(&pict);
+						SDL_UpdateYUVTexture(texture, NULL, data[0], linesize[0],
+								data[1], linesize[1],
+								data[2], linesize[2]);
+						av_freep(&data[0]);
 					}
 					else
 					{
@@ -306,18 +311,18 @@ bool CVideoPlayer::nextFrame()
 						size_t pic_bytes = dest->pitch * dest->h;
 						size_t ffmped_pad = 1024; /* a few bytes of overflow will go here */
 						void * for_sws = av_malloc (pic_bytes + ffmped_pad);
-						pict.data[0] = (ui8 *)for_sws;
-						pict.linesize[0] = dest->pitch;
+						data[0] = (ui8 *)for_sws;
+						linesize[0] = dest->pitch;
 
 						sws_scale(sws, frame->data, frame->linesize,
-								  0, codecContext->height, pict.data, pict.linesize);
+								  0, codecContext->height, data, linesize);
 						memcpy(dest->pixels, for_sws, pic_bytes);
 						av_free(for_sws);
 					}
 				}
 			}
 
-			av_free_packet(&packet);
+			av_packet_unref(&packet);
 		}
 	}
 
@@ -401,6 +406,10 @@ void CVideoPlayer::close()
 	{
 		avcodec_close(codecContext);
 		codec = nullptr;
+	}
+	if (codecContext)
+	{
+		avcodec_free_context(&codecContext);
 		codecContext = nullptr;
 	}
 

+ 3 - 1
client/CVideoHandler.h

@@ -59,6 +59,8 @@ public:
 
 extern "C" {
 #include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/imgutils.h>
 #include <libswscale/swscale.h>
 }
 
@@ -94,7 +96,7 @@ class CVideoPlayer : public IMainVideoPlayer
 	int stream;					// stream index in video
 	AVFormatContext *format;
 	AVCodecContext *codecContext; // codec context for stream
-	AVCodec *codec;
+	const AVCodec *codec;
 	AVFrame *frame;
 	struct SwsContext *sws;