diff --git a/avidemux/common/ADM_editor/include/ADM_edit.hxx b/avidemux/common/ADM_editor/include/ADM_edit.hxx index d6efe3c223..5bab09e0b4 100644 --- a/avidemux/common/ADM_editor/include/ADM_edit.hxx +++ b/avidemux/common/ADM_editor/include/ADM_edit.hxx @@ -161,6 +161,9 @@ protected: ADM_PP *_pp; // Postprocessing settings ADMToneMapperConfig *_hdrConfig; ADMImage *_imageBuffer; // Temp buffer used for decoding + ADMColorScalerFull *_rescueScaler; + int _rescueScalerWidth, _rescueScalerHeight; + ADM_pixelFormat _rescueScalerPixFmt; uint64_t _currentPts; // Current image PTS uint32_t _currentSegment; // Current video segment int64_t _nextFrameDts; // COPYMODE Used in copy mode to fill the missing timestamp diff --git a/avidemux/common/ADM_editor/src/ADM_edRenderInternal.cpp b/avidemux/common/ADM_editor/src/ADM_edRenderInternal.cpp index 6df87e02e3..0bdccc6cf5 100644 --- a/avidemux/common/ADM_editor/src/ADM_edRenderInternal.cpp +++ b/avidemux/common/ADM_editor/src/ADM_edRenderInternal.cpp @@ -407,6 +407,41 @@ bool ADM_Composer::decompressImage(ADMImage *out,ADMCompressedImage *in,uint32_t return true; } + // handle if decoded frame resolution changed !?! + if ((tmpImage->_width != _imageBuffer->_width) || (tmpImage->_height != _imageBuffer->_height)) + { + if (!refOnly) + ADM_assert(0); + if(tmpImage->refType == ADM_HW_NONE) + { + if (_rescueScaler == NULL) + { + _rescueScaler = new ADMColorScalerFull(ADM_CS_BICUBIC,tmpImage->_width,tmpImage->_height,_imageBuffer->_width,_imageBuffer->_height,tmpImage->_pixfrmt,ADM_PIXFRMT_YV12); + _rescueScalerWidth = tmpImage->_width; + _rescueScalerHeight = tmpImage->_height; + _rescueScalerPixFmt = tmpImage->_pixfrmt; + + } + else + if ((tmpImage->_width != _rescueScalerWidth) || (tmpImage->_height != _rescueScalerHeight) || (_rescueScalerPixFmt != tmpImage->_pixfrmt)) + { + _rescueScaler->reset(ADM_CS_BICUBIC,tmpImage->_width,tmpImage->_height,_imageBuffer->_width,_imageBuffer->_height,tmpImage->_pixfrmt,ADM_PIXFRMT_YV12); + _rescueScalerWidth = tmpImage->_width; + _rescueScalerHeight = tmpImage->_height; + _rescueScalerPixFmt = tmpImage->_pixfrmt; + } + + _rescueScaler->convertImage(tmpImage,_imageBuffer); + _imageBuffer->copyInfo(tmpImage); + tmpImage = _imageBuffer; + } + else // HW image unsupported + { + return false; + } + } + + if (_blankImageForInfo==NULL) { _blankImageForInfo = new ADMImageRef(tmpImage->_width,tmpImage->_height); diff --git a/avidemux/common/ADM_editor/src/ADM_edit.cpp b/avidemux/common/ADM_editor/src/ADM_edit.cpp index 0216ed46e2..af1d13f6db 100644 --- a/avidemux/common/ADM_editor/src/ADM_edit.cpp +++ b/avidemux/common/ADM_editor/src/ADM_edit.cpp @@ -49,6 +49,7 @@ ADM_Composer::ADM_Composer (void) _pp=NULL; _hdrConfig=NULL; _imageBuffer=NULL; + _rescueScaler=NULL; _internalFlags=0; _currentSegment=0; _scratch=NULL; @@ -585,6 +586,11 @@ uint8_t ADM_Composer::addFile (const char *name) delete _imageBuffer; _imageBuffer=NULL; } + if (_rescueScaler) + { + delete _rescueScaler; + _rescueScaler=NULL; + } _imageBuffer=new ADMImageDefault(info.width,info.height); _imageBuffer->_qSize= ((info.width+15)>>4)*((info.height+15)>>4); _imageBuffer->quant=new uint8_t[_imageBuffer->_qSize]; @@ -950,6 +956,11 @@ uint8_t ADM_Composer::cleanup (void) delete _imageBuffer; _imageBuffer=NULL; } + if (_rescueScaler) + { + delete _rescueScaler; + _rescueScaler=NULL; + } if (_blankImageForInfo) { diff --git a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_dxva2.cpp b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_dxva2.cpp index aa6685b397..39b68431a6 100644 --- a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_dxva2.cpp +++ b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_dxva2.cpp @@ -562,6 +562,8 @@ bool decoderFFDXVA2::readBackBuffer(AVFrame *decodedFrame, ADMCompressedImag out->refDescriptor.refMarkUsed =dxvaMarkSurfaceUsed; out->refDescriptor.refMarkUnused=dxvaMarkSurfaceUnused; out->refDescriptor.refDownload =dxvaRefDownload; + out->_width = decodedFrame->width; // out is ref, we can do this + out->_height = decodedFrame->height; return true; } //--- diff --git a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_libva.cpp b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_libva.cpp index a2d88dee5f..330bec05e0 100644 --- a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_libva.cpp +++ b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_libva.cpp @@ -579,6 +579,8 @@ bool decoderFFLIBVA::readBackBuffer(AVFrame *decodedFrame, ADMCompressedImag out->refDescriptor.refMarkUsed=libvaMarkSurfaceUsed; out->refDescriptor.refMarkUnused=libvaMarkSurfaceUnused; out->refDescriptor.refDownload=libvaRefDownload; + out->_width = decodedFrame->width; // out is ref, we can do this + out->_height = decodedFrame->height; return true; } diff --git a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_vdpau.cpp b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_vdpau.cpp index 9f1f0f2cf4..dec8c12661 100644 --- a/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_vdpau.cpp +++ b/avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_vdpau.cpp @@ -454,6 +454,8 @@ bool decoderFFVDPAU::readBackBuffer(AVFrame *decodedFrame, ADMCompressedImag out->Pts= (uint64_t)(pts_opaque); out->flags=admFrameTypeFromLav(decodedFrame); out->_range=(decodedFrame->color_range==AVCOL_RANGE_JPEG)? ADM_COL_RANGE_JPEG : ADM_COL_RANGE_MPEG; + out->_width = decodedFrame->width; // out is ref, we can do this + out->_height = decodedFrame->height; return true; } diff --git a/avidemux_core/ADM_coreVideoCodec/src/ADM_ffmp43.cpp b/avidemux_core/ADM_coreVideoCodec/src/ADM_ffmp43.cpp index 8b3f0f6d27..7662ef4d06 100644 --- a/avidemux_core/ADM_coreVideoCodec/src/ADM_ffmp43.cpp +++ b/avidemux_core/ADM_coreVideoCodec/src/ADM_ffmp43.cpp @@ -209,6 +209,8 @@ uint8_t decoderFF::clonePic (AVFrame * src, ADMImage * out, bool swap) break; } } + out->_width = src->width; // out is ref, we can do this + out->_height = src->height; return 1; } diff --git a/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexH264.cpp b/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexH264.cpp index 6f800b3370..a314e8ac98 100644 --- a/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexH264.cpp +++ b/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexH264.cpp @@ -447,11 +447,13 @@ uint8_t TsIndexerH264::run(const char *file, ADM_TS_TRACK *videoTrac) spsInfo.width, spsInfo.height, tmpInfo.width, tmpInfo.height, data.nbPics, thisUnit.packetInfo.startAt); char alert[1024]; alert[0]='\0'; - snprintf(alert,1024,QT_TRANSLATE_NOOP("tsdemuxer","The size of the video changes at frame %u " - "from %ux%u to %ux%u. This is unsupported and will result in a crash.\n" + snprintf(alert,1024,QT_TRANSLATE_NOOP("tsdemuxer","The resolution of the video changes from %ux%u to %ux%u " + "at frame %u.\nIf hardware decoders are enabled, this will result in a crash.\n" + "Software decoder will scale every frame to %ux%u.\n" + "Scaling will affect re-encode, but not copy mode.\n" "Proceed nevertheless?\n" "This warning won't be shown again for this video."), - data.nbPics, spsInfo.width, spsInfo.height, tmpInfo.width, tmpInfo.height); + spsInfo.width, spsInfo.height, tmpInfo.width, tmpInfo.height, data.nbPics, spsInfo.width, spsInfo.height); alert[1023]='\0'; if(!warningIgnored && !GUI_Question(alert,true)) { diff --git a/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexMpeg2.cpp b/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexMpeg2.cpp index e1d12069cb..8a90e36a62 100644 --- a/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexMpeg2.cpp +++ b/avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexMpeg2.cpp @@ -174,11 +174,13 @@ uint8_t result=1; video.w, video.h, widthToCheck, heightToCheck, data.nbPics, spsUnit.packetInfo.startAt); char alert[1024]; alert[0]='\0'; - snprintf(alert,1024,QT_TRANSLATE_NOOP("tsdemuxer","The size of the video changes at frame %u " - "from %ux%u to %ux%u. This is unsupported and will result in a crash.\n" + snprintf(alert,1024,QT_TRANSLATE_NOOP("tsdemuxer","The resolution of the video changes from %ux%u to %ux%u " + "at frame %u.\nIf hardware decoders are enabled, this will result in a crash.\n" + "Software decoder will scale every frame to %ux%u.\n" + "Scaling will affect re-encode, but not copy mode.\n" "Proceed nevertheless?\n" "This warning won't be shown again for this video."), - data.nbPics, video.w, video.h, widthToCheck, heightToCheck); + video.w, video.h, widthToCheck, heightToCheck, data.nbPics, video.w, video.h); alert[1023]='\0'; if(!warningIgnored && !GUI_Question(alert,true)) goto the_end; diff --git a/avidemux_plugins/ADM_videoDecoder/aom/ADM_aomDec.cpp b/avidemux_plugins/ADM_videoDecoder/aom/ADM_aomDec.cpp index fae4f925f9..3bc33e5605 100644 --- a/avidemux_plugins/ADM_videoDecoder/aom/ADM_aomDec.cpp +++ b/avidemux_plugins/ADM_videoDecoder/aom/ADM_aomDec.cpp @@ -146,6 +146,8 @@ bool decoderAom::uncompress(ADMCompressedImage *in, ADMImage *out) r->Pts=in->demuxerPts; r->flags=in->flags; + r->_width = img->w; + r->_height = img->h; // make sure the output is not marked as a hw image int count = 0; while(r->refType != ADM_HW_NONE && count < 32 /* arbitrary limit */) diff --git a/avidemux_plugins/ADM_videoDecoder/vpx/ADM_vpx.cpp b/avidemux_plugins/ADM_videoDecoder/vpx/ADM_vpx.cpp index 18432700ea..c0b84b96cb 100644 --- a/avidemux_plugins/ADM_videoDecoder/vpx/ADM_vpx.cpp +++ b/avidemux_plugins/ADM_videoDecoder/vpx/ADM_vpx.cpp @@ -113,6 +113,8 @@ bool decoderVPX::uncompress (ADMCompressedImage * in, ADMImage * out) r->_pixfrmt=ADM_PIXFRMT_YV12; r->Pts=in->demuxerPts; r->flags=in->flags; + r->_width = img->w; + r->_height = img->h; return true; }