# HG changeset patch # User Gianfranco Costamagna # Date 1388755299 -3600 # Node ID 113e61a8cadccee68bfa6d6e0bee3a1d637182eb # Parent 5071f5682733f63019f61882c924721b3df82676 Fixed avwrapper exit calls, fixing issue 752 diff -r 5071f5682733 -r 113e61a8cadc hedgewars/avwrapper/avwrapper.c --- a/hedgewars/avwrapper/avwrapper.c Fri Jan 03 07:09:28 2014 -0800 +++ b/hedgewars/avwrapper/avwrapper.c Fri Jan 03 14:21:39 2014 +0100 @@ -65,7 +65,7 @@ // pointer to function from hwengine (uUtils.pas) static void (*AddFileLogRaw)(const char* pString); -static void FatalError(const char* pFmt, ...) +static int FatalError(const char* pFmt, ...) { char Buffer[1024]; va_list VaArgs; @@ -77,7 +77,7 @@ AddFileLogRaw("Error in av-wrapper: "); AddFileLogRaw(Buffer); AddFileLogRaw("\n"); - exit(1); + return(-1); } // Function to be called from libav for logging. @@ -166,7 +166,7 @@ } } -// returns non-zero if there is more sound +// returns non-zero if there is more sound, -1 in case of error static int WriteAudioFrame() { if (!g_pAStream) @@ -189,7 +189,7 @@ // when NumSamples == 0 we still need to call encode_audio2 to flush int got_packet; if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0) - FatalError("avcodec_encode_audio2 failed"); + return FatalError("avcodec_encode_audio2 failed"); if (!got_packet) return 0; #else @@ -210,12 +210,12 @@ // Write the compressed frame to the media file. Packet.stream_index = g_pAStream->index; if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing audio frame"); + return FatalError("Error while writing audio frame"); return 1; } // add a video output stream -static void AddVideoStream() +static int AddVideoStream() { #if LIBAVFORMAT_VERSION_MAJOR >= 53 g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec); @@ -223,7 +223,7 @@ g_pVStream = av_new_stream(g_pContainer, 0); #endif if (!g_pVStream) - FatalError("Could not allocate video stream"); + return FatalError("Could not allocate video stream"); g_pVideo = g_pVStream->codec; @@ -297,29 +297,35 @@ #else if (avcodec_open(g_pVideo, g_pVCodec) < 0) #endif - FatalError("Could not open video codec %s", g_pVCodec->long_name); + return FatalError("Could not open video codec %s", g_pVCodec->long_name); g_pVFrame = avcodec_alloc_frame(); if (!g_pVFrame) - FatalError("Could not allocate frame"); + return FatalError("Could not allocate frame"); g_pVFrame->linesize[0] = g_Width; g_pVFrame->linesize[1] = g_Width/2; g_pVFrame->linesize[2] = g_Width/2; g_pVFrame->linesize[3] = 0; + return 0; } static int WriteFrame(AVFrame* pFrame) { double AudioTime, VideoTime; - + int ret; // write interleaved audio frame if (g_pAStream) { VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den; do + { AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den; - while (AudioTime < VideoTime && WriteAudioFrame()); + ret = WriteAudioFrame(); + } + while (AudioTime < VideoTime && ret); + if (ret < 0) + return ret; } if (!g_pVStream) @@ -341,7 +347,7 @@ Packet.size = sizeof(AVPicture); if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); + return FatalError("Error while writing video frame"); return 0; } else @@ -349,7 +355,7 @@ #if LIBAVCODEC_VERSION_MAJOR >= 54 int got_packet; if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0) - FatalError("avcodec_encode_video2 failed"); + return FatalError("avcodec_encode_video2 failed"); if (!got_packet) return 0; @@ -360,7 +366,7 @@ #else Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame); if (Packet.size < 0) - FatalError("avcodec_encode_video failed"); + return FatalError("avcodec_encode_video failed"); if (Packet.size == 0) return 0; @@ -373,21 +379,21 @@ // write the compressed frame in the media file Packet.stream_index = g_pVStream->index; if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); + return FatalError("Error while writing video frame"); return 1; } } -AVWRAP_DECL void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) +AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) { g_pVFrame->data[0] = pY; g_pVFrame->data[1] = pCb; g_pVFrame->data[2] = pCr; - WriteFrame(g_pVFrame); + return WriteFrame(g_pVFrame); } -AVWRAP_DECL void AVWrapper_Init( +AVWRAP_DECL int AVWrapper_Init( void (*pAddFileLogRaw)(const char*), const char* pFilename, const char* pDesc, @@ -399,6 +405,7 @@ int FramerateNum, int FramerateDen, int VQuality) { + int ret; AddFileLogRaw = pAddFileLogRaw; av_log_set_callback( &LogCallback ); @@ -414,12 +421,12 @@ // find format g_pFormat = av_guess_format(pFormatName, NULL, NULL); if (!g_pFormat) - FatalError("Format \"%s\" was not found", pFormatName); + return FatalError("Format \"%s\" was not found", pFormatName); // allocate the output media context g_pContainer = avformat_alloc_context(); if (!g_pContainer) - FatalError("Could not allocate output context"); + return FatalError("Could not allocate output context"); g_pContainer->oformat = g_pFormat; @@ -442,7 +449,11 @@ g_pAStream = NULL; if (g_pVCodec) - AddVideoStream(); + { + ret = AddVideoStream(); + if (ret < 0) + return ret; + } else Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName); @@ -462,7 +473,7 @@ Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName); if (!g_pAStream && !g_pVStream) - FatalError("No video, no audio, aborting..."); + return FatalError("No video, no audio, aborting..."); // write format info to log av_dump_format(g_pContainer, 0, g_pContainer->filename, 1); @@ -471,22 +482,36 @@ if (!(g_pFormat->flags & AVFMT_NOFILE)) { if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0) - FatalError("Could not open output file (%s)", g_pContainer->filename); + return FatalError("Could not open output file (%s)", g_pContainer->filename); } // write the stream header, if any avformat_write_header(g_pContainer, NULL); g_pVFrame->pts = -1; + return 0; } -AVWRAP_DECL void AVWrapper_Close() +AVWRAP_DECL int AVWrapper_Close() { + int ret; // output buffered frames if (g_pVCodec->capabilities & CODEC_CAP_DELAY) - while( WriteFrame(NULL) ); + { + do + ret = WriteFrame(NULL); + while (ret); + if (ret < 0) + return ret; + } // output any remaining audio - while( WriteAudioFrame() ); + do + { + ret = WriteAudioFrame(); + } + while(ret); + if (ret < 0) + return ret; // write the trailer, if any. av_write_trailer(g_pContainer); @@ -514,4 +539,5 @@ } av_free(g_pContainer); + return 0; } diff -r 5071f5682733 -r 113e61a8cadc hedgewars/uVideoRec.pas --- a/hedgewars/uVideoRec.pas Fri Jan 03 07:09:28 2014 -0800 +++ b/hedgewars/uVideoRec.pas Fri Jan 03 14:21:39 2014 +0100 @@ -53,12 +53,12 @@ type TAddFileLogRaw = procedure (s: pchar); cdecl; const AvwrapperLibName = 'libavwrapper'; -procedure AVWrapper_Init( +function AVWrapper_Init( AddLog: TAddFileLogRaw; filename, desc, soundFile, format, vcodec, acodec: PChar; - width, height, framerateNum, framerateDen, vquality: LongInt); cdecl; external AvwrapperLibName; -procedure AVWrapper_Close; cdecl; external AvwrapperLibName; -procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AvwrapperLibName; + width, height, framerateNum, framerateDen, vquality: LongInt): LongInt; cdecl; external AvwrapperLibName; +function AVWrapper_Close: LongInt; cdecl; external AvwrapperLibName; +function AVWrapper_WriteFrame( pY, pCb, pCr: PByte ): LongInt; cdecl; external AvwrapperLibName; type TFrame = record realTicks: LongWord; @@ -109,14 +109,15 @@ filename:= UserPathPrefix + '/VideoTemp/' + RecPrefix; soundFilePath:= UserPathPrefix + '/VideoTemp/' + RecPrefix + '.sw'; - AVWrapper_Init(@AddFileLogRaw + if AVWrapper_Init(@AddFileLogRaw , PChar(ansistring(filename)) , PChar(ansistring(desc)) , PChar(ansistring(soundFilePath)) , PChar(ansistring(cAVFormat)) , PChar(ansistring(cVideoCodec)) , PChar(ansistring(cAudioCodec)) - , cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, cVideoQuality); + , cScreenWidth, cScreenHeight, cVideoFramerateNum, cVideoFramerateDen, cVideoQuality) < 0 then + halt(-1); numPixels:= cScreenWidth*cScreenHeight; YCbCr_Planes[0]:= GetMem(numPixels); @@ -150,7 +151,8 @@ FreeMem(YCbCr_Planes[2], numPixels div 4); FreeMem(RGB_Buffer, 4*numPixels); Close(cameraFile); - AVWrapper_Close(); + if AVWrapper_Close() < 0 then + halt(-1); Erase(cameraFile); DeleteFile(soundFilePath); SendIPC(_S'v'); // inform frontend that we finished @@ -185,7 +187,8 @@ YCbCr_Planes[2][y*(cScreenWidth div 2) + x]:= Byte(128 + (( 7196*r - 6026*g - 1170*b) shr 16)); end; - AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]); + if AVWrapper_WriteFrame(YCbCr_Planes[0], YCbCr_Planes[1], YCbCr_Planes[2]) < 0 then + halt(-1); // inform frontend that we have encoded new frame s[0]:= #3;