mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	decode: be more explicit about storing the last packet properties
The current code stores a pointer to the packet passed to the decoder, which is then used during get_buffer() for timestamps and side data passthrough. However, since this is a pointer to user data which we do not own, storing it is potentially dangerous. It is also ill defined for the new decoding API with split input/output. Fix this problem by making an explicit internally owned copy of the packet properties.
This commit is contained in:
		| @@ -99,6 +99,14 @@ fail2: | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) | ||||||
|  | { | ||||||
|  |     av_packet_unref(avci->last_pkt_props); | ||||||
|  |     if (pkt) | ||||||
|  |         return av_packet_copy_props(avci->last_pkt_props, pkt); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) | static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) | ||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
| @@ -304,7 +312,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi | |||||||
|         return AVERROR(ENOSYS); |         return AVERROR(ENOSYS); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     avctx->internal->pkt = avpkt; |     ret = extract_packet_props(avci, avpkt); | ||||||
|  |     if (ret < 0) | ||||||
|  |         return ret; | ||||||
|  |  | ||||||
|     ret = apply_param_change(avctx, avpkt); |     ret = apply_param_change(avctx, avpkt); | ||||||
|     if (ret < 0) |     if (ret < 0) | ||||||
|         return ret; |         return ret; | ||||||
| @@ -368,7 +379,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, | |||||||
|         return AVERROR(ENOSYS); |         return AVERROR(ENOSYS); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     avctx->internal->pkt = avpkt; |     ret = extract_packet_props(avci, avpkt); | ||||||
|  |     if (ret < 0) | ||||||
|  |         return ret; | ||||||
|  |  | ||||||
|     if (!avpkt->data && avpkt->size) { |     if (!avpkt->data && avpkt->size) { | ||||||
|         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); |         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); | ||||||
| @@ -408,7 +421,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, | |||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
|  |  | ||||||
|     avctx->internal->pkt = avpkt; |     ret = extract_packet_props(avctx->internal, avpkt); | ||||||
|  |     if (ret < 0) | ||||||
|  |         return ret; | ||||||
|  |  | ||||||
|     *got_sub_ptr = 0; |     *got_sub_ptr = 0; | ||||||
|     ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); |     ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); | ||||||
|     if (*got_sub_ptr) |     if (*got_sub_ptr) | ||||||
| @@ -739,7 +755,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags | |||||||
|  |  | ||||||
| int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) | int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) | ||||||
| { | { | ||||||
|     AVPacket *pkt = avctx->internal->pkt; |     AVPacket *pkt = avctx->internal->last_pkt_props; | ||||||
|     int i; |     int i; | ||||||
|     struct { |     struct { | ||||||
|         enum AVPacketSideDataType packet; |         enum AVPacketSideDataType packet; | ||||||
| @@ -759,15 +775,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) | |||||||
|     frame->chroma_location = avctx->chroma_sample_location; |     frame->chroma_location = avctx->chroma_sample_location; | ||||||
|  |  | ||||||
|     frame->reordered_opaque = avctx->reordered_opaque; |     frame->reordered_opaque = avctx->reordered_opaque; | ||||||
|     if (!pkt) { |  | ||||||
| #if FF_API_PKT_PTS |  | ||||||
| FF_DISABLE_DEPRECATION_WARNINGS |  | ||||||
|         frame->pkt_pts = AV_NOPTS_VALUE; |  | ||||||
| FF_ENABLE_DEPRECATION_WARNINGS |  | ||||||
| #endif |  | ||||||
|         frame->pts     = AV_NOPTS_VALUE; |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| #if FF_API_PKT_PTS | #if FF_API_PKT_PTS | ||||||
| FF_DISABLE_DEPRECATION_WARNINGS | FF_DISABLE_DEPRECATION_WARNINGS | ||||||
|   | |||||||
| @@ -131,10 +131,10 @@ typedef struct AVCodecInternal { | |||||||
|     void *thread_ctx; |     void *thread_ctx; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Current packet as passed into the decoder, to avoid having to pass the |      * Properties (timestamps+side data) extracted from the last packet passed | ||||||
|      * packet into every function. |      * for decoding. | ||||||
|      */ |      */ | ||||||
|     AVPacket *pkt; |     AVPacket *last_pkt_props; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * hwaccel-specific private data |      * hwaccel-specific private data | ||||||
|   | |||||||
| @@ -656,7 +656,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) | |||||||
|         } |         } | ||||||
|         *copy->internal = *src->internal; |         *copy->internal = *src->internal; | ||||||
|         copy->internal->thread_ctx = p; |         copy->internal->thread_ctx = p; | ||||||
|         copy->internal->pkt = &p->avpkt; |         copy->internal->last_pkt_props = &p->avpkt; | ||||||
|  |  | ||||||
|         if (!i) { |         if (!i) { | ||||||
|             src = copy; |             src = copy; | ||||||
|   | |||||||
| @@ -433,6 +433,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code | |||||||
|         goto free_and_end; |         goto free_and_end; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     avctx->internal->last_pkt_props = av_packet_alloc(); | ||||||
|  |     if (!avctx->internal->last_pkt_props) { | ||||||
|  |         ret = AVERROR(ENOMEM); | ||||||
|  |         goto free_and_end; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (codec->priv_data_size > 0) { |     if (codec->priv_data_size > 0) { | ||||||
|         if (!avctx->priv_data) { |         if (!avctx->priv_data) { | ||||||
|             avctx->priv_data = av_mallocz(codec->priv_data_size); |             avctx->priv_data = av_mallocz(codec->priv_data_size); | ||||||
| @@ -713,6 +719,7 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||||
|         av_frame_free(&avctx->internal->to_free); |         av_frame_free(&avctx->internal->to_free); | ||||||
|         av_frame_free(&avctx->internal->buffer_frame); |         av_frame_free(&avctx->internal->buffer_frame); | ||||||
|         av_packet_free(&avctx->internal->buffer_pkt); |         av_packet_free(&avctx->internal->buffer_pkt); | ||||||
|  |         av_packet_free(&avctx->internal->last_pkt_props); | ||||||
|         av_freep(&avctx->internal->pool); |         av_freep(&avctx->internal->pool); | ||||||
|     } |     } | ||||||
|     av_freep(&avctx->internal); |     av_freep(&avctx->internal); | ||||||
| @@ -753,6 +760,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) | |||||||
|         av_frame_free(&avctx->internal->to_free); |         av_frame_free(&avctx->internal->to_free); | ||||||
|         av_frame_free(&avctx->internal->buffer_frame); |         av_frame_free(&avctx->internal->buffer_frame); | ||||||
|         av_packet_free(&avctx->internal->buffer_pkt); |         av_packet_free(&avctx->internal->buffer_pkt); | ||||||
|  |         av_packet_free(&avctx->internal->last_pkt_props); | ||||||
|         for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) |         for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) | ||||||
|             av_buffer_pool_uninit(&pool->pools[i]); |             av_buffer_pool_uninit(&pool->pools[i]); | ||||||
|         av_freep(&avctx->internal->pool); |         av_freep(&avctx->internal->pool); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anton Khirnov
					Anton Khirnov