Quoting wm4 (2015-10-09 16:56:30) > On Fri, 9 Oct 2015 16:26:16 +0200 > Luca Barbato <[email protected]> wrote: > > > --- > > libavcodec/Makefile | 1 + > > libavcodec/allcodecs.c | 1 + > > libavcodec/avcodec.h | 1 + > > libavcodec/codec_desc.c | 7 ++++ > > libavcodec/wrapped_avframe.c | 94 > > ++++++++++++++++++++++++++++++++++++++++++++ > > 5 files changed, 104 insertions(+) > > create mode 100644 libavcodec/wrapped_avframe.c > > > > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > > index ba711ae..3e57a0d 100644 > > --- a/libavcodec/Makefile > > +++ b/libavcodec/Makefile > > @@ -472,6 +472,7 @@ OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o > > wmv2.o \ > > msmpeg4.o msmpeg4enc.o > > msmpeg4data.o > > OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o > > OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o > > +OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o > > OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o > > OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o > > OBJS-$(CONFIG_XAN_WC4_DECODER) += xxan.o > > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > > index 2d8474a..46febd5 100644 > > --- a/libavcodec/allcodecs.c > > +++ b/libavcodec/allcodecs.c > > @@ -292,6 +292,7 @@ void avcodec_register_all(void) > > REGISTER_DECODER(VP9, vp9); > > REGISTER_DECODER(VQA, vqa); > > REGISTER_DECODER(WEBP, webp); > > + REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe); > > REGISTER_ENCDEC (WMV1, wmv1); > > REGISTER_ENCDEC (WMV2, wmv2); > > REGISTER_DECODER(WMV3, wmv3); > > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > > index 11ae1fc..1494d7b 100644 > > --- a/libavcodec/avcodec.h > > +++ b/libavcodec/avcodec.h > > @@ -300,6 +300,7 @@ enum AVCodecID { > > AV_CODEC_ID_DDS, > > AV_CODEC_ID_DXV, > > AV_CODEC_ID_SCREENPRESSO, > > + AV_CODEC_ID_WRAPPED_AVFRAME, > > > > /* various PCM "codecs" */ > > AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the > > start of audio codecs > > diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c > > index d2c7a91..91c77c8 100644 > > --- a/libavcodec/codec_desc.c > > +++ b/libavcodec/codec_desc.c > > @@ -1169,6 +1169,13 @@ static const AVCodecDescriptor codec_descriptors[] = > > { > > .long_name = NULL_IF_CONFIG_SMALL("Screenpresso"), > > .props = AV_CODEC_PROP_LOSSLESS, > > }, > > + { > > + .id = AV_CODEC_ID_WRAPPED_AVFRAME, > > + .type = AVMEDIA_TYPE_VIDEO, > > + .name = "wrapped_avframe", > > + .long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket > > passthrough"), > > + .props = AV_CODEC_PROP_LOSSLESS, > > + }, > > > > /* image codecs */ > > { > > diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c > > new file mode 100644 > > index 0000000..527ddda > > --- /dev/null > > +++ b/libavcodec/wrapped_avframe.c > > @@ -0,0 +1,94 @@ > > +/* > > + * AVFrame wrapper > > + * Copyright (c) 2015 Luca Barbato > > + * > > + * This file is part of Libav. > > + * > > + * Libav is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2.1 of the License, or (at your option) any later version. > > + * > > + * Libav is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with Libav; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > > 02110-1301 USA > > + */ > > + > > +/** > > + * @file > > + * Simple wrapper to store an AVFrame and forward it as AVPacket. > > + */ > > + > > +#include "avcodec.h" > > +#include "internal.h" > > + > > +#include "libavutil/internal.h" > > +#include "libavutil/frame.h" > > +#include "libavutil/buffer.h" > > +#include "libavutil/pixdesc.h" > > + > > +static av_cold int wrapped_avframe_encode_init(AVCodecContext *avctx) > > +{ > > + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); > > + > > +#if FF_API_CODED_FRAME > > +FF_DISABLE_DEPRECATION_WARNINGS > > + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; > > + avctx->coded_frame->key_frame = 1; > > +FF_ENABLE_DEPRECATION_WARNINGS > > +#endif > > Explanation? > > > + avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc); > > + > > + return 0; > > +} > > + > > +static void wrapped_avframe_release_buffer(void *unused, uint8_t *data) > > +{ > > + AVFrame *frame = (AVFrame *)data; > > + > > + av_frame_free(&frame); > > +} > > + > > +static int wrapped_avframe_encode(AVCodecContext *avctx, AVPacket *pkt, > > + const AVFrame *frame, int *got_packet) > > +{ > > + AVFrame *wrapped = av_frame_alloc(); > > + int ret; > > + > > + if (!wrapped) > > + return AVERROR(ENOMEM); > > + > > + > > + ret = av_frame_ref(wrapped, frame); > > + if (ret < 0) > > + return ret; > > + > > + pkt->buf = av_buffer_create((uint8_t *)wrapped, sizeof(wrapped), > > + wrapped_avframe_release_buffer, NULL, > > + AV_BUFFER_FLAG_READONLY); > > + if (!pkt->buf) { > > + av_frame_free(&wrapped); > > + return AVERROR(ENOMEM); > > + } > > + > > + pkt->data = (uint8_t *)wrapped; > > + pkt->size = sizeof(wrapped); > > + > > In theory, sizeof(AVFrame) is not allowed, because it's defined in > libavutil, and the size of the struct is not part of the ABI. I wonder > if this requires changing this? If everything else fails, we could just > wrap a pointer to an AVFrame, instead of an AVFrame itself.
I think sizeof(AVFrame) is kind of ok in this case. At least I don't see how it could seriously break anything. The receiver of such a packet would technically not be allowed to access the fields that exist in the frame, but this encoder does not know about. But that's probably not a huge deal. -- Anton Khirnov _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
