mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 07:49:59 +01:00
avcodec/decode: use ff_frame_new_side_data() to export Exif side data
Otherwise, the user requested priority of packet side data will be ignored. Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -2268,12 +2268,10 @@ static int attach_displaymatrix(AVCodecContext *avctx, AVFrame *frame, int orien
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd, AVBufferRef *og)
|
static int exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd, AVBufferRef **pbuf)
|
||||||
{
|
{
|
||||||
const AVExifEntry *orient = NULL;
|
const AVExifEntry *orient = NULL;
|
||||||
AVFrameSideData *sd;
|
|
||||||
AVExifMetadata *cloned = NULL;
|
AVExifMetadata *cloned = NULL;
|
||||||
AVBufferRef *written = NULL;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (size_t i = 0; i < ifd->count; i++) {
|
for (size_t i = 0; i < ifd->count; i++) {
|
||||||
@@ -2305,25 +2303,21 @@ static int exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMe
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (cloned || !og) {
|
if (cloned || !*pbuf) {
|
||||||
ret = av_exif_write(avctx, ifd, &written, AV_EXIF_TIFF_HEADER);
|
av_buffer_unref(pbuf);
|
||||||
|
ret = av_exif_write(avctx, ifd, pbuf, AV_EXIF_TIFF_HEADER);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_EXIF, written ? written : og);
|
ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_EXIF, pbuf);
|
||||||
if (!sd) {
|
if (ret < 0)
|
||||||
if (written)
|
|
||||||
av_buffer_unref(&written);
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (og && written && ret >= 0)
|
av_buffer_unref(pbuf);
|
||||||
av_buffer_unref(&og); // as though we called new_side_data on og;
|
|
||||||
av_exif_free(cloned);
|
av_exif_free(cloned);
|
||||||
av_free(cloned);
|
av_free(cloned);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2331,22 +2325,25 @@ end:
|
|||||||
|
|
||||||
int ff_decode_exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd)
|
int ff_decode_exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd)
|
||||||
{
|
{
|
||||||
return exif_attach_ifd(avctx, frame, ifd, NULL);
|
AVBufferRef *dummy = NULL;
|
||||||
|
return exif_attach_ifd(avctx, frame, ifd, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef *data,
|
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef **pbuf,
|
||||||
enum AVExifHeaderMode header_mode)
|
enum AVExifHeaderMode header_mode)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
AVBufferRef *data = *pbuf;
|
||||||
AVExifMetadata ifd = { 0 };
|
AVExifMetadata ifd = { 0 };
|
||||||
|
|
||||||
ret = av_exif_parse_buffer(avctx, data->data, data->size, &ifd, header_mode);
|
ret = av_exif_parse_buffer(avctx, data->data, data->size, &ifd, header_mode);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
ret = exif_attach_ifd(avctx, frame, &ifd, data);
|
ret = exif_attach_ifd(avctx, frame, &ifd, pbuf);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
av_buffer_unref(pbuf);
|
||||||
av_exif_free(&ifd);
|
av_exif_free(&ifd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,11 +230,10 @@ enum AVExifHeaderMode;
|
|||||||
* attaches that information as an AV_FRAME_DATA_DISPLAYMATRIX instead
|
* attaches that information as an AV_FRAME_DATA_DISPLAYMATRIX instead
|
||||||
* of including it in the AV_FRAME_DATA_EXIF side data buffer.
|
* of including it in the AV_FRAME_DATA_EXIF side data buffer.
|
||||||
*
|
*
|
||||||
* On a success, the caller loses ownership of the data buffer. Either it is
|
* *buf is ALWAYS consumed by this function and NULL written in its place, even
|
||||||
* unrefed, or its ownership is transferred to the frame directly. On failure,
|
* on failure.
|
||||||
* the data buffer is left owned by the caller.
|
|
||||||
*/
|
*/
|
||||||
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef *data,
|
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef **buf,
|
||||||
enum AVExifHeaderMode header_mode);
|
enum AVExifHeaderMode header_mode);
|
||||||
|
|
||||||
struct AVExifMetadata;
|
struct AVExifMetadata;
|
||||||
|
|||||||
@@ -1753,15 +1753,12 @@ exit_loop:
|
|||||||
if (s->exif_data) {
|
if (s->exif_data) {
|
||||||
// we swap because ff_decode_exif_attach_buffer adds to p->metadata
|
// we swap because ff_decode_exif_attach_buffer adds to p->metadata
|
||||||
FFSWAP(AVDictionary *, p->metadata, s->frame_metadata);
|
FFSWAP(AVDictionary *, p->metadata, s->frame_metadata);
|
||||||
ret = ff_decode_exif_attach_buffer(avctx, p, s->exif_data, AV_EXIF_TIFF_HEADER);
|
ret = ff_decode_exif_attach_buffer(avctx, p, &s->exif_data, AV_EXIF_TIFF_HEADER);
|
||||||
FFSWAP(AVDictionary *, p->metadata, s->frame_metadata);
|
FFSWAP(AVDictionary *, p->metadata, s->frame_metadata);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
|
av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// ff_decode_exif_attach_buffer takes ownership so
|
|
||||||
// we do not want to call av_buffer_unref here
|
|
||||||
s->exif_data = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->color_type == PNG_COLOR_TYPE_PALETTE && avctx->codec_id == AV_CODEC_ID_APNG) {
|
if (s->color_type == PNG_COLOR_TYPE_PALETTE && avctx->codec_id == AV_CODEC_ID_APNG) {
|
||||||
|
|||||||
@@ -1479,12 +1479,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
s->has_exif = 1;
|
s->has_exif = 1;
|
||||||
memcpy(exif_buf->data, gb.buffer, chunk_size);
|
memcpy(exif_buf->data, gb.buffer, chunk_size);
|
||||||
|
|
||||||
/* if this succeeds then exif_buf is either freed or transferred to the AVFrame */
|
ret = ff_decode_exif_attach_buffer(avctx, p, &exif_buf, AV_EXIF_TIFF_HEADER);
|
||||||
ret = ff_decode_exif_attach_buffer(avctx, p, exif_buf, AV_EXIF_TIFF_HEADER);
|
if (ret < 0)
|
||||||
if (ret < 0) {
|
|
||||||
av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
|
av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
|
||||||
av_buffer_unref(&exif_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
exif_end:
|
exif_end:
|
||||||
bytestream2_skip(&gb, chunk_size);
|
bytestream2_skip(&gb, chunk_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user