Showing the changes to libavcodec (7 of 8 files). Show all
Unified · Split
| @@ -46,6 +46,7 @@ OBJS = ac3_parser.o \ · 45 unmodified lines | |||
| 46 | get_buffer.o \ | 46 | get_buffer.o \ |
| 47 | imgconvert.o \ | 47 | imgconvert.o \ |
| 48 | jni.o \ | 48 | jni.o \ |
| 49 | lcevcdec.o \ | ||
| 49 | mathtables.o \ | 50 | mathtables.o \ |
| 50 | mediacodec.o \ | 51 | mediacodec.o \ |
| 51 | mpeg12framerate.o \ | 52 | mpeg12framerate.o \ |
| @@ -446,6 +446,8 @@ av_cold void ff_codec_close(AVCodecContext *avctx) · 445 unmodified lines | |||
| 446 | 446 | ||
| 447 | ff_refstruct_unref(&avci->pool); | 447 | ff_refstruct_unref(&avci->pool); |
| 448 | ff_refstruct_pool_uninit(&avci->progress_frame_pool); | 448 | ff_refstruct_pool_uninit(&avci->progress_frame_pool); |
| 449 | if (av_codec_is_decoder(avctx->codec)) | ||
| 450 | ff_decode_internal_uninit(avctx); | ||
| 449 | 451 | ||
| 450 | ff_hwaccel_uninit(avctx); | 452 | ff_hwaccel_uninit(avctx); |
| 451 | 453 | ||
| @@ -68,6 +68,10 @@ void ff_decode_flush_buffers(struct AVCodecContext *avctx); · 67 unmodified lines | |||
| 68 | void ff_encode_flush_buffers(struct AVCodecContext *avctx); | 68 | void ff_encode_flush_buffers(struct AVCodecContext *avctx); |
| 69 | 69 | ||
| 70 | struct AVCodecInternal *ff_decode_internal_alloc(void); | 70 | struct AVCodecInternal *ff_decode_internal_alloc(void); |
| 71 | void ff_decode_internal_sync(struct AVCodecContext *dst, | ||
| 72 | const struct AVCodecContext *src); | ||
| 73 | void ff_decode_internal_uninit(struct AVCodecContext *avctx); | ||
| 74 | |||
| 71 | struct AVCodecInternal *ff_encode_internal_alloc(void); | 75 | struct AVCodecInternal *ff_encode_internal_alloc(void); |
| 72 | 76 | ||
| 73 | void ff_codec_close(struct AVCodecContext *avctx); | 77 | void ff_codec_close(struct AVCodecContext *avctx); |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | |||
| 48 | #include "hwaccel_internal.h" | 48 | #include "hwaccel_internal.h" |
| 49 | #include "hwconfig.h" | 49 | #include "hwconfig.h" |
| 50 | #include "internal.h" | 50 | #include "internal.h" |
| 51 | #include "lcevcdec.h" | ||
| 51 | #include "packet_internal.h" | 52 | #include "packet_internal.h" |
| 52 | #include "progressframe.h" | 53 | #include "progressframe.h" |
| 53 | #include "refstruct.h" | 54 | #include "refstruct.h" |
| @@ -89,6 +90,11 @@ typedef struct DecodeContext { · 35 unmodified lines | |||
| 89 | * (global or attached to packets) side data over bytestream. | 90 | * (global or attached to packets) side data over bytestream. |
| 90 | */ | 91 | */ |
| 91 | uint64_t side_data_pref_mask; | 92 | uint64_t side_data_pref_mask; |
| 93 | |||
| 94 | FFLCEVCContext *lcevc; | ||
| 95 | int lcevc_frame; | ||
| 96 | int width; | ||
| 97 | int height; | ||
| 92 | } DecodeContext; | 98 | } DecodeContext; |
| 93 | 99 | ||
| 94 | static DecodeContext *decode_ctx(AVCodecInternal *avci) | 100 | static DecodeContext *decode_ctx(AVCodecInternal *avci) |
| @@ -1597,6 +1603,40 @@ int ff_attach_decode_data(AVFrame *frame) · 1502 unmodified lines | |||
| 1597 | return 0; | 1603 | return 0; |
| 1598 | } | 1604 | } |
| 1599 | 1605 | ||
| 1606 | static void update_frame_props(AVCodecContext *avctx, AVFrame *frame) | ||
| 1607 | { | ||
| 1608 | AVCodecInternal *avci = avctx->internal; | ||
| 1609 | DecodeContext *dc = decode_ctx(avci); | ||
| 1610 | |||
| 1611 | dc->lcevc_frame = dc->lcevc && avctx->codec_type == AVMEDIA_TYPE_VIDEO && | ||
| 1612 | av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC); | ||
| 1613 | |||
| 1614 | if (dc->lcevc_frame) { | ||
| 1615 | dc->width = frame->width; | ||
| 1616 | dc->height = frame->height; | ||
| 1617 | frame->width = frame->width * 2 / FFMAX(frame->sample_aspect_ratio.den, 1); | ||
| 1618 | frame->height = frame->height * 2 / FFMAX(frame->sample_aspect_ratio.num, 1); | ||
| 1619 | } | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | static void attach_post_process_data(AVCodecContext *avctx, AVFrame *frame) | ||
| 1623 | { | ||
| 1624 | AVCodecInternal *avci = avctx->internal; | ||
| 1625 | DecodeContext *dc = decode_ctx(avci); | ||
| 1626 | |||
| 1627 | if (dc->lcevc_frame) { | ||
| 1628 | FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; | ||
| 1629 | |||
| 1630 | fdd->post_process_opaque = ff_refstruct_ref(dc->lcevc); | ||
| 1631 | fdd->post_process_opaque_free = ff_lcevc_unref; | ||
| 1632 | fdd->post_process = ff_lcevc_process; | ||
| 1633 | |||
| 1634 | frame->width = dc->width; | ||
| 1635 | frame->height = dc->height; | ||
| 1636 | } | ||
| 1637 | dc->lcevc_frame = 0; | ||
| 1638 | } | ||
| 1639 | |||
| 1600 | int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) | 1640 | int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) |
| 1601 | { | 1641 | { |
| 1602 | const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); | 1642 | const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); |
| @@ -1640,8 +1680,10 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) · 37 unmodified lines | |||
| 1640 | ret = hwaccel->alloc_frame(avctx, frame); | 1680 | ret = hwaccel->alloc_frame(avctx, frame); |
| 1641 | goto end; | 1681 | goto end; |
| 1642 | } | 1682 | } |
| 1643 | } else | 1683 | } else { |
| 1644 | avctx->sw_pix_fmt = avctx->pix_fmt; | 1684 | avctx->sw_pix_fmt = avctx->pix_fmt; |
| 1685 | update_frame_props(avctx, frame); | ||
| 1686 | } | ||
| 1645 | 1687 | ||
| 1646 | ret = avctx->get_buffer2(avctx, frame, flags); | 1688 | ret = avctx->get_buffer2(avctx, frame, flags); |
| 1647 | if (ret < 0) | 1689 | if (ret < 0) |
| @@ -1653,6 +1695,8 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) · 5 unmodified lines | |||
| 1653 | if (ret < 0) | 1695 | if (ret < 0) |
| 1654 | goto fail; | 1696 | goto fail; |
| 1655 | 1697 | ||
| 1698 | attach_post_process_data(avctx, frame); | ||
| 1699 | |||
| 1656 | end: | 1700 | end: |
| 1657 | if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && | 1701 | if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && |
| 1658 | !(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { | 1702 | !(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { |
| @@ -1953,6 +1997,12 @@ int ff_decode_preinit(AVCodecContext *avctx) · 294 unmodified lines | |||
| 1953 | if (ret < 0) | 1997 | if (ret < 0) |
| 1954 | return ret; | 1998 | return ret; |
| 1955 | 1999 | ||
| 2000 | if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) { | ||
| 2001 | ret = ff_lcevc_alloc(&dc->lcevc); | ||
| 2002 | if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) | ||
| 2003 | return ret; | ||
| 2004 | } | ||
| 2005 | |||
| 1956 | #if FF_API_DROPCHANGED | 2006 | #if FF_API_DROPCHANGED |
| 1957 | if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) | 2007 | if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) |
| 1958 | av_log(avctx, AV_LOG_WARNING, "The dropchanged flag is deprecated.\n"); | 2008 | av_log(avctx, AV_LOG_WARNING, "The dropchanged flag is deprecated.\n"); |
| @@ -2187,3 +2237,19 @@ AVCodecInternal *ff_decode_internal_alloc(void) · 228 unmodified lines | |||
| 2187 | { | 2237 | { |
| 2188 | return av_mallocz(sizeof(DecodeContext)); | 2238 | return av_mallocz(sizeof(DecodeContext)); |
| 2189 | } | 2239 | } |
| 2240 | |||
| 2241 | void ff_decode_internal_sync(AVCodecContext *dst, const AVCodecContext *src) | ||
| 2242 | { | ||
| 2243 | const DecodeContext *src_dc = decode_ctx(src->internal); | ||
| 2244 | DecodeContext *dst_dc = decode_ctx(dst->internal); | ||
| 2245 | |||
| 2246 | ff_refstruct_replace(&dst_dc->lcevc, src_dc->lcevc); | ||
| 2247 | } | ||
| 2248 | |||
| 2249 | void ff_decode_internal_uninit(AVCodecContext *avctx) | ||
| 2250 | { | ||
| 2251 | AVCodecInternal *avci = avctx->internal; | ||
| 2252 | DecodeContext *dc = decode_ctx(avci); | ||
| 2253 | |||
| 2254 | ff_refstruct_unref(&dc->lcevc); | ||
| 2255 | } | ||
| @@ -0,0 +1,319 @@ | |||
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "config_components.h" | ||
| 20 | |||
| 21 | #include "libavutil/avassert.h" | ||
| 22 | #include "libavutil/frame.h" | ||
| 23 | #include "libavutil/imgutils.h" | ||
| 24 | #include "libavutil/log.h" | ||
| 25 | #include "libavutil/mem.h" | ||
| 26 | #include "decode.h" | ||
| 27 | #include "lcevcdec.h" | ||
| 28 | |||
| 29 | #if CONFIG_LIBLCEVC_DEC | ||
| 30 | static LCEVC_ColorFormat map_format(int format) | ||
| 31 | { | ||
| 32 | switch (format) { | ||
| 33 | case AV_PIX_FMT_YUV420P: | ||
| 34 | return LCEVC_I420_8; | ||
| 35 | case AV_PIX_FMT_YUV420P10: | ||
| 36 | return LCEVC_I420_10_LE; | ||
| 37 | case AV_PIX_FMT_NV12: | ||
| 38 | return LCEVC_NV12_8; | ||
| 39 | case AV_PIX_FMT_NV21: | ||
| 40 | return LCEVC_NV21_8; | ||
| 41 | case AV_PIX_FMT_GRAY8: | ||
| 42 | return LCEVC_GRAY_8; | ||
| 43 | } | ||
| 44 | |||
| 45 | return LCEVC_ColorFormat_Unknown; | ||
| 46 | } | ||
| 47 | |||
| 48 | static int alloc_base_frame(void *logctx, LCEVC_DecoderHandle decoder, | ||
| 49 | const AVFrame *frame, LCEVC_PictureHandle *picture) | ||
| 50 | { | ||
| 51 | LCEVC_PictureDesc desc; | ||
| 52 | LCEVC_ColorFormat fmt = map_format(frame->format); | ||
| 53 | LCEVC_PictureLockHandle lock; | ||
| 54 | uint8_t *data[4] = { NULL }; | ||
| 55 | int linesizes[4] = { 0 }; | ||
| 56 | uint32_t planes; | ||
| 57 | LCEVC_ReturnCode res; | ||
| 58 | |||
| 59 | res = LCEVC_DefaultPictureDesc(&desc, fmt, frame->width, frame->height); | ||
| 60 | if (res != LCEVC_Success) | ||
| 61 | return AVERROR_EXTERNAL; | ||
| 62 | |||
| 63 | desc.cropTop = frame->crop_top; | ||
| 64 | desc.cropBottom = frame->crop_bottom; | ||
| 65 | desc.cropLeft = frame->crop_left; | ||
| 66 | desc.cropRight = frame->crop_right; | ||
| 67 | desc.sampleAspectRatioNum = frame->sample_aspect_ratio.num; | ||
| 68 | desc.sampleAspectRatioDen = frame->sample_aspect_ratio.den; | ||
| 69 | |||
| 70 | /* Allocate LCEVC Picture */ | ||
| 71 | res = LCEVC_AllocPicture(decoder, &desc, picture); | ||
| 72 | if (res != LCEVC_Success) { | ||
| 73 | return AVERROR_EXTERNAL; | ||
| 74 | } | ||
| 75 | res = LCEVC_LockPicture(decoder, *picture, LCEVC_Access_Write, &lock); | ||
| 76 | if (res != LCEVC_Success) | ||
| 77 | return AVERROR_EXTERNAL; | ||
| 78 | |||
| 79 | res = LCEVC_GetPicturePlaneCount(decoder, *picture, &planes); | ||
| 80 | if (res != LCEVC_Success) | ||
| 81 | return AVERROR_EXTERNAL; | ||
| 82 | |||
| 83 | for (unsigned i = 0; i < planes; i++) { | ||
| 84 | LCEVC_PicturePlaneDesc plane; | ||
| 85 | |||
| 86 | res = LCEVC_GetPictureLockPlaneDesc(decoder, lock, i, &plane); | ||
| 87 | if (res != LCEVC_Success) | ||
| 88 | return AVERROR_EXTERNAL; | ||
| 89 | |||
| 90 | data[i] = plane.firstSample; | ||
| 91 | linesizes[i] = plane.rowByteStride; | ||
| 92 | } | ||
| 93 | |||
| 94 | av_image_copy2(data, linesizes, frame->data, frame->linesize, | ||
| 95 | frame->format, frame->width, frame->height); | ||
| 96 | |||
| 97 | res = LCEVC_UnlockPicture(decoder, lock); | ||
| 98 | if (res != LCEVC_Success) | ||
| 99 | return AVERROR_EXTERNAL; | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int alloc_enhanced_frame(void *logctx, LCEVC_DecoderHandle decoder, | ||
| 105 | const AVFrame *frame, LCEVC_PictureHandle *picture) | ||
| 106 | { | ||
| 107 | LCEVC_PictureDesc desc ; | ||
| 108 | LCEVC_ColorFormat fmt = map_format(frame->format); | ||
| 109 | LCEVC_PicturePlaneDesc planes[4] = { 0 }; | ||
| 110 | int width = frame->width * 2 / FFMAX(frame->sample_aspect_ratio.den, 1); | ||
| 111 | int height = frame->height * 2 / FFMAX(frame->sample_aspect_ratio.num, 1); | ||
| 112 | LCEVC_ReturnCode res; | ||
| 113 | |||
| 114 | res = LCEVC_DefaultPictureDesc(&desc, fmt, width, height); | ||
| 115 | if (res != LCEVC_Success) | ||
| 116 | return AVERROR_EXTERNAL; | ||
| 117 | |||
| 118 | /* Set plane description */ | ||
| 119 | for (int i = 0; i < 4; i++) { | ||
| 120 | planes[i].firstSample = frame->data[i]; | ||
| 121 | planes[i].rowByteStride = frame->linesize[i]; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* Allocate LCEVC Picture */ | ||
| 125 | res = LCEVC_AllocPictureExternal(decoder, &desc, NULL, planes, picture); | ||
| 126 | if (res != LCEVC_Success) { | ||
| 127 | return AVERROR_EXTERNAL; | ||
| 128 | } | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int lcevc_send_frame(void *logctx, FFLCEVCContext *lcevc, const AVFrame *in) | ||
| 133 | { | ||
| 134 | const AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_LCEVC); | ||
| 135 | LCEVC_PictureHandle picture; | ||
| 136 | LCEVC_ReturnCode res; | ||
| 137 | int ret = 0; | ||
| 138 | |||
| 139 | if (!sd) | ||
| 140 | return 1; | ||
| 141 | |||
| 142 | res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, 0, sd->data, sd->size); | ||
| 143 | if (res != LCEVC_Success) | ||
| 144 | return AVERROR_EXTERNAL; | ||
| 145 | |||
| 146 | ret = alloc_base_frame(logctx, lcevc->decoder, in, &picture); | ||
| 147 | if (ret < 0) | ||
| 148 | return ret; | ||
| 149 | |||
| 150 | res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, NULL); | ||
| 151 | if (res != LCEVC_Success) | ||
| 152 | return AVERROR_EXTERNAL; | ||
| 153 | |||
| 154 | memset(&picture, 0, sizeof(picture)); | ||
| 155 | ret = alloc_enhanced_frame(logctx, lcevc->decoder, in, &picture); | ||
| 156 | if (ret < 0) | ||
| 157 | return ret; | ||
| 158 | |||
| 159 | res = LCEVC_SendDecoderPicture(lcevc->decoder, picture); | ||
| 160 | if (res != LCEVC_Success) | ||
| 161 | return AVERROR_EXTERNAL; | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | static int generate_output(void *logctx, FFLCEVCContext *lcevc, AVFrame *out) | ||
| 167 | { | ||
| 168 | LCEVC_PictureDesc desc; | ||
| 169 | LCEVC_DecodeInformation info; | ||
| 170 | LCEVC_PictureHandle picture; | ||
| 171 | LCEVC_ReturnCode res; | ||
| 172 | |||
| 173 | res = LCEVC_ReceiveDecoderPicture(lcevc->decoder, &picture, &info); | ||
| 174 | if (res != LCEVC_Success) | ||
| 175 | return AVERROR_EXTERNAL; | ||
| 176 | |||
| 177 | res = LCEVC_GetPictureDesc(lcevc->decoder, picture, &desc); | ||
| 178 | if (res != LCEVC_Success) | ||
| 179 | return AVERROR_EXTERNAL; | ||
| 180 | |||
| 181 | out->crop_top = desc.cropTop; | ||
| 182 | out->crop_bottom = desc.cropBottom; | ||
| 183 | out->crop_left = desc.cropLeft; | ||
| 184 | out->crop_right = desc.cropRight; | ||
| 185 | out->sample_aspect_ratio.num = desc.sampleAspectRatioNum; | ||
| 186 | out->sample_aspect_ratio.den = desc.sampleAspectRatioDen; | ||
| 187 | out->width = desc.width + out->crop_left + out->crop_right; | ||
| 188 | out->height = desc.height + out->crop_top + out->crop_bottom; | ||
| 189 | |||
| 190 | res = LCEVC_FreePicture(lcevc->decoder, picture); | ||
| 191 | if (res != LCEVC_Success) | ||
| 192 | return AVERROR_EXTERNAL; | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | static int lcevc_receive_frame(void *logctx, FFLCEVCContext *lcevc, AVFrame *out) | ||
| 198 | { | ||
| 199 | LCEVC_PictureHandle picture; | ||
| 200 | LCEVC_ReturnCode res; | ||
| 201 | int ret; | ||
| 202 | |||
| 203 | ret = generate_output(logctx, lcevc, out); | ||
| 204 | if (ret < 0) | ||
| 205 | return ret; | ||
| 206 | |||
| 207 | while (1) { | ||
| 208 | res = LCEVC_ReceiveDecoderBase (lcevc->decoder, &picture); | ||
| 209 | if (res != LCEVC_Success && res != LCEVC_Again) | ||
| 210 | return AVERROR_EXTERNAL; | ||
| 211 | |||
| 212 | if (res == LCEVC_Again) | ||
| 213 | break; | ||
| 214 | |||
| 215 | res = LCEVC_FreePicture(lcevc->decoder, picture); | ||
| 216 | if (res != LCEVC_Success) | ||
| 217 | return AVERROR_EXTERNAL; | ||
| 218 | } | ||
| 219 | |||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, | ||
| 224 | LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info, | ||
| 225 | const uint8_t *data, uint32_t size, void *logctx) | ||
| 226 | { | ||
| 227 | switch (event) { | ||
| 228 | case LCEVC_Log: | ||
| 229 | av_log(logctx, AV_LOG_INFO, "%s\n", data); | ||
| 230 | break; | ||
| 231 | default: | ||
| 232 | break; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | static void lcevc_free(FFRefStructOpaque unused, void *obj) | ||
| 237 | { | ||
| 238 | FFLCEVCContext *lcevc = obj; | ||
| 239 | if (lcevc->initialized) | ||
| 240 | LCEVC_DestroyDecoder(lcevc->decoder); | ||
| 241 | memset(lcevc, 0, sizeof(*lcevc)); | ||
| 242 | } | ||
| 243 | #endif | ||
| 244 | |||
| 245 | static int lcevc_init(FFLCEVCContext *lcevc, void *logctx) | ||
| 246 | { | ||
| 247 | #if CONFIG_LIBLCEVC_DEC | ||
| 248 | LCEVC_AccelContextHandle dummy = { 0 }; | ||
| 249 | const int32_t event = LCEVC_Log; | ||
| 250 | #endif | ||
| 251 | |||
| 252 | if (lcevc->initialized) | ||
| 253 | return 0; | ||
| 254 | |||
| 255 | #if CONFIG_LIBLCEVC_DEC | ||
| 256 | if (LCEVC_CreateDecoder(&lcevc->decoder, dummy) != LCEVC_Success) { | ||
| 257 | av_log(logctx, AV_LOG_ERROR, "Failed to create LCEVC decoder\n"); | ||
| 258 | return AVERROR_EXTERNAL; | ||
| 259 | } | ||
| 260 | |||
| 261 | LCEVC_ConfigureDecoderInt(lcevc->decoder, "log_level", 4); | ||
| 262 | LCEVC_ConfigureDecoderIntArray(lcevc->decoder, "events", 1, &event); | ||
| 263 | LCEVC_SetDecoderEventCallback(lcevc->decoder, event_callback, logctx); | ||
| 264 | |||
| 265 | if (LCEVC_InitializeDecoder(lcevc->decoder) != LCEVC_Success) { | ||
| 266 | av_log(logctx, AV_LOG_ERROR, "Failed to initialize LCEVC decoder\n"); | ||
| 267 | LCEVC_DestroyDecoder(lcevc->decoder); | ||
| 268 | return AVERROR_EXTERNAL; | ||
| 269 | } | ||
| 270 | |||
| 271 | #endif | ||
| 272 | lcevc->initialized = 1; | ||
| 273 | |||
| 274 | return 0; | ||
| 275 | } | ||
| 276 | |||
| 277 | int ff_lcevc_process(void *logctx, AVFrame *frame) | ||
| 278 | { | ||
| 279 | FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; | ||
| 280 | FFLCEVCContext *lcevc = fdd->post_process_opaque; | ||
| 281 | int ret; | ||
| 282 | |||
| 283 | if (!lcevc->initialized) { | ||
| 284 | ret = lcevc_init(lcevc, logctx); | ||
| 285 | if (ret < 0) | ||
| 286 | return ret; | ||
| 287 | } | ||
| 288 | |||
| 289 | #if CONFIG_LIBLCEVC_DEC | ||
| 290 | ret = lcevc_send_frame(logctx, lcevc, frame); | ||
| 291 | if (ret) | ||
| 292 | return ret < 0 ? ret : 0; | ||
| 293 | |||
| 294 | lcevc_receive_frame(logctx, lcevc, frame); | ||
| 295 | if (ret < 0) | ||
| 296 | return ret; | ||
| 297 | |||
| 298 | av_frame_remove_side_data(frame, AV_FRAME_DATA_LCEVC); | ||
| 299 | #endif | ||
| 300 | |||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | int ff_lcevc_alloc(FFLCEVCContext **plcevc) | ||
| 305 | { | ||
| 306 | FFLCEVCContext *lcevc = NULL; | ||
| 307 | #if CONFIG_LIBLCEVC_DEC | ||
| 308 | lcevc = ff_refstruct_alloc_ext(sizeof(*lcevc), 0, NULL, lcevc_free); | ||
| 309 | if (!lcevc) | ||
| 310 | return AVERROR(ENOMEM); | ||
| 311 | #endif | ||
| 312 | *plcevc = lcevc; | ||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | |||
| 316 | void ff_lcevc_unref(void *opaque) | ||
| 317 | { | ||
| 318 | ff_refstruct_unref(&opaque); | ||
| 319 | } | ||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef AVCODEC_LCEVCDEC_H | ||
| 20 | #define AVCODEC_LCEVCDEC_H | ||
| 21 | |||
| 22 | #include "config_components.h" | ||
| 23 | |||
| 24 | #include <stdint.h> | ||
| 25 | #if CONFIG_LIBLCEVC_DEC | ||
| 26 | #include <LCEVC/lcevc_dec.h> | ||
| 27 | #else | ||
| 28 | typedef uintptr_t LCEVC_DecoderHandle; | ||
| 29 | #endif | ||
| 30 | #include "refstruct.h" | ||
| 31 | |||
| 32 | typedef struct FFLCEVCContext { | ||
| 33 | LCEVC_DecoderHandle decoder; | ||
| 34 | int initialized; | ||
| 35 | } FFLCEVCContext; | ||
| 36 | |||
| 37 | struct AVFrame; | ||
| 38 | |||
| 39 | int ff_lcevc_alloc(FFLCEVCContext **plcevc); | ||
| 40 | int ff_lcevc_process(void *logctx, struct AVFrame *frame); | ||
| 41 | void ff_lcevc_unref(void *opaque); | ||
| 42 | #endif /* AVCODEC_LCEVCDEC_H */ | ||
| @@ -406,6 +406,7 @@ FF_ENABLE_DEPRECATION_WARNINGS · 405 unmodified lines | |||
| 406 | dst->hwaccel_flags = src->hwaccel_flags; | 406 | dst->hwaccel_flags = src->hwaccel_flags; |
| 407 | 407 | ||
| 408 | ff_refstruct_replace(&dst->internal->pool, src->internal->pool); | 408 | ff_refstruct_replace(&dst->internal->pool, src->internal->pool); |
| 409 | ff_decode_internal_sync(dst, src); | ||
| 409 | } | 410 | } |
| 410 | 411 | ||
| 411 | if (for_user) { | 412 | if (for_user) { |
| @@ -782,6 +783,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) · 370 unmodified lines | |||
| 782 | ff_refstruct_unref(&ctx->internal->pool); | 783 | ff_refstruct_unref(&ctx->internal->pool); |
| 783 | av_packet_free(&ctx->internal->in_pkt); | 784 | av_packet_free(&ctx->internal->in_pkt); |
| 784 | av_packet_free(&ctx->internal->last_pkt_props); | 785 | av_packet_free(&ctx->internal->last_pkt_props); |
| 786 | ff_decode_internal_uninit(ctx); | ||
| 785 | av_freep(&ctx->internal); | 787 | av_freep(&ctx->internal); |
| 786 | av_buffer_unref(&ctx->hw_frames_ctx); | 788 | av_buffer_unref(&ctx->hw_frames_ctx); |
| 787 | av_frame_side_data_free(&ctx->decoded_side_data, | 789 | av_frame_side_data_free(&ctx->decoded_side_data, |
| @@ -845,6 +847,7 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, · 57 unmodified lines | |||
| 845 | copy->internal = ff_decode_internal_alloc(); | 847 | copy->internal = ff_decode_internal_alloc(); |
| 846 | if (!copy->internal) | 848 | if (!copy->internal) |
| 847 | return AVERROR(ENOMEM); | 849 | return AVERROR(ENOMEM); |
| 850 | ff_decode_internal_sync(copy, avctx); | ||
| 848 | copy->internal->thread_ctx = p; | 851 | copy->internal->thread_ctx = p; |
| 849 | copy->internal->progress_frame_pool = avctx->internal->progress_frame_pool; | 852 | copy->internal->progress_frame_pool = avctx->internal->progress_frame_pool; |
| 850 | 853 | ||