Message ID | 1472643361-10118-4-git-send-email-erkki.seppala.ext@nokia.com |
---|---|
State | Changes Requested |
Headers | show |
Hi! 2016-08-31 13:35 GMT+02:00 Erkki Seppälä <erkki.seppala.ext@nokia.com>: > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > index 6ac6646..0d0447e6 100644 > --- a/libavcodec/avcodec.h > +++ b/libavcodec/avcodec.h > @@ -639,7 +639,7 @@ enum AVCodecID { > AV_CODEC_ID_DVD_NAV, > AV_CODEC_ID_TIMED_ID3, > AV_CODEC_ID_BIN_DATA, > - > + AV_CODEC_ID_META, Please do not remove the empty line. > diff --git a/libavcodec/metacodec.c b/libavcodec/metacodec.c > new file mode 100644 > index 0000000..bd8013c > --- /dev/null > +++ b/libavcodec/metacodec.c > @@ -0,0 +1,95 @@ > +/* > + * Copyright (c) 2015 Erkki Seppälä <erkki.seppala.ext@nokia.com> > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg 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. > + * > + * FFmpeg 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 FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include "libavutil/intreadwrite.h" > +#include "internal.h" > +#include "libavutil/opt.h" > +#include "libavformat/avio.h" > + > +static int meta_encode(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, > + int *got_packet_ptr) > +{ > + *got_packet_ptr = 0; > + > + av_packet_unref(avpkt); > + if (frame->buf) { > + avpkt->buf = av_buffer_ref(frame->buf[0]); > + if (!avpkt->buf) > + return AVERROR(ENOMEM); > + avpkt->data = frame->data[0]; > + } else { > + avpkt->buf = av_buffer_alloc(frame->nb_samples); > + if (!avpkt->buf) > + return AVERROR(ENOMEM); > + avpkt->data = avpkt->buf; > + memcpy(avpkt->data, frame->data[0], frame->nb_samples); > + } > + avpkt->size = frame->nb_samples; > + avpkt->pts = frame->pts; > + avpkt->dts = frame->pts; > + *got_packet_ptr = 1; > + > + return 0; > +} > + > +static int meta_decode(AVCodecContext *avctx, void *data, int *got_packet_ptr, AVPacket *avpkt) > +{ > + AVFrame *metadata = data; > + > + *got_packet_ptr = 0; > + > + av_frame_unref(metadata); > + if (avpkt->buf) { > + metadata->buf[0] = av_buffer_ref(avpkt->buf); > + if (!metadata->buf[0]) > + return AVERROR(ENOMEM); > + metadata->buf[0]->size = avpkt->size; > + } else { > + metadata->buf[0] = av_buffer_alloc(avpkt->size); > + if (!metadata->buf[0]) > + return AVERROR(ENOMEM); > + metadata->data[0] = metadata->buf[0]->data; > + memcpy(metadata->data[0], avpkt->data, avpkt->size); > + } > + > + metadata->nb_samples = avpkt->size; > + metadata->pts = avpkt->pts; > + metadata->pkt_pts = avpkt->pts; > + metadata->pkt_dts = avpkt->dts; > + *got_packet_ptr = 1; > + > + return 0; > +} > + > +AVCodec ff_meta_encoder = { > + .name = "meta", > + .long_name = NULL_IF_CONFIG_SMALL("Metadata Encoder"), > + .type = AVMEDIA_TYPE_DATA, > + .id = AV_CODEC_ID_META, > + .encode2 = meta_encode, > +}; > + > +AVCodec ff_meta_decoder = { > + .name = "meta", > + .long_name = NULL_IF_CONFIG_SMALL("Metadata Decoder"), > + .type = AVMEDIA_TYPE_DATA, > + .id = AV_CODEC_ID_META, > + .decode = meta_decode, > +}; You either have to add some "#if"'s around the code - configure allows to enable / disable the encoders and decoders separately - or split the file. Since the encoder and decoder do not share code, this seems simpler, Carl Eugen
On Wed, Aug 31, 2016 at 02:35:46PM +0300, Erkki Seppälä wrote: > It has the codec id AV_CODEC_ID_META and type of AVMEDIA_TYPE_DATA. > > This codec basically passes the data forward and is used for referring > timed meta data tracks by a codec. It is useful for dealing with the > metadata in a similar way as other kinds of codecs. > > Signed-off-by: Erkki Seppälä <erkki.seppala.ext@nokia.com> > Signed-off-by: OZOPlayer <OZOPL@nokia.com> > --- > configure | 4 +-- > libavcodec/Makefile | 2 +- > libavcodec/allcodecs.c | 3 ++ > libavcodec/avcodec.h | 2 +- > libavcodec/codec_desc.c | 8 +++++ > libavcodec/metacodec.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 110 insertions(+), 4 deletions(-) > create mode 100644 libavcodec/metacodec.c [...] > diff --git a/libavcodec/metacodec.c b/libavcodec/metacodec.c > new file mode 100644 > index 0000000..bd8013c > --- /dev/null > +++ b/libavcodec/metacodec.c this causes a compiler warning: libavcodec/metacodec.c: In function ‘meta_encode’: libavcodec/metacodec.c:41:21: warning: assignment from incompatible pointer type [enabled by default] [...]
On 09/01/2016 08:01 PM, Michael Niedermayer wrote: > this causes a compiler warning: > libavcodec/metacodec.c: In function ‘meta_encode’: > libavcodec/metacodec.c:41:21: warning: assignment from incompatible pointer type [enabled by default] > avpkt->buf = av_buffer_alloc(frame->nb_samples); > if (!avpkt->buf) > return AVERROR(ENOMEM); > avpkt->data = avpkt->buf; /* warning */ > memcpy(avpkt->data, frame->data[0], frame->nb_samples); Oops. Fixed. I now understand why FFmpeg prefers uint8_t* over void*..
diff --git a/configure b/configure index 9b92426..ded5452 100755 --- a/configure +++ b/configure @@ -2848,11 +2848,11 @@ matroska_demuxer_select="iso_media riffdec" matroska_demuxer_suggest="bzlib lzo zlib" matroska_muxer_select="iso_media riffenc" mmf_muxer_select="riffenc" -mov_demuxer_select="iso_media riffdec" +mov_demuxer_select="iso_media riffdec meta_decoder" mov_demuxer_suggest="zlib" mov_muxer_select="iso_media riffenc rtpenc_chain" mp3_demuxer_select="mpegaudio_parser" -mp4_muxer_select="mov_muxer" +mp4_muxer_select="mov_muxer meta_encoder" mpegts_demuxer_select="iso_media" mpegts_muxer_select="adts_muxer latm_muxer" mpegtsraw_demuxer_select="mpegts_demuxer" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index a6e79ce..98a7a8d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -799,7 +799,7 @@ OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o # libavformat dependencies -OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o +OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o metacodec.o OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o OBJS-$(CONFIG_CAF_DEMUXER) += ac3tab.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4c6b94e..30d0243 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -687,4 +687,7 @@ void avcodec_register_all(void) REGISTER_PARSER(VP3, vp3); REGISTER_PARSER(VP8, vp8); REGISTER_PARSER(VP9, vp9); + + /* data, meta data */ + REGISTER_ENCDEC(META, meta); } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 6ac6646..0d0447e6 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -639,7 +639,7 @@ enum AVCodecID { AV_CODEC_ID_DVD_NAV, AV_CODEC_ID_TIMED_ID3, AV_CODEC_ID_BIN_DATA, - + AV_CODEC_ID_META, AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24948ca..e85b51d 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2965,6 +2965,14 @@ static const AVCodecDescriptor codec_descriptors[] = { .mime_types= MT("application/octet-stream"), }, + { + .id = AV_CODEC_ID_META, + .type = AVMEDIA_TYPE_DATA, + .name = "meta_data", + .long_name = NULL_IF_CONFIG_SMALL("binary data"), + .mime_types= MT("application/octet-stream"), + }, + /* deprecated codec ids */ }; diff --git a/libavcodec/metacodec.c b/libavcodec/metacodec.c new file mode 100644 index 0000000..bd8013c --- /dev/null +++ b/libavcodec/metacodec.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015 Erkki Seppälä <erkki.seppala.ext@nokia.com> + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/intreadwrite.h" +#include "internal.h" +#include "libavutil/opt.h" +#include "libavformat/avio.h" + +static int meta_encode(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, + int *got_packet_ptr) +{ + *got_packet_ptr = 0; + + av_packet_unref(avpkt); + if (frame->buf) { + avpkt->buf = av_buffer_ref(frame->buf[0]); + if (!avpkt->buf) + return AVERROR(ENOMEM); + avpkt->data = frame->data[0]; + } else { + avpkt->buf = av_buffer_alloc(frame->nb_samples); + if (!avpkt->buf) + return AVERROR(ENOMEM); + avpkt->data = avpkt->buf; + memcpy(avpkt->data, frame->data[0], frame->nb_samples); + } + avpkt->size = frame->nb_samples; + avpkt->pts = frame->pts; + avpkt->dts = frame->pts; + *got_packet_ptr = 1; + + return 0; +} + +static int meta_decode(AVCodecContext *avctx, void *data, int *got_packet_ptr, AVPacket *avpkt) +{ + AVFrame *metadata = data; + + *got_packet_ptr = 0; + + av_frame_unref(metadata); + if (avpkt->buf) { + metadata->buf[0] = av_buffer_ref(avpkt->buf); + if (!metadata->buf[0]) + return AVERROR(ENOMEM); + metadata->buf[0]->size = avpkt->size; + } else { + metadata->buf[0] = av_buffer_alloc(avpkt->size); + if (!metadata->buf[0]) + return AVERROR(ENOMEM); + metadata->data[0] = metadata->buf[0]->data; + memcpy(metadata->data[0], avpkt->data, avpkt->size); + } + + metadata->nb_samples = avpkt->size; + metadata->pts = avpkt->pts; + metadata->pkt_pts = avpkt->pts; + metadata->pkt_dts = avpkt->dts; + *got_packet_ptr = 1; + + return 0; +} + +AVCodec ff_meta_encoder = { + .name = "meta", + .long_name = NULL_IF_CONFIG_SMALL("Metadata Encoder"), + .type = AVMEDIA_TYPE_DATA, + .id = AV_CODEC_ID_META, + .encode2 = meta_encode, +}; + +AVCodec ff_meta_decoder = { + .name = "meta", + .long_name = NULL_IF_CONFIG_SMALL("Metadata Decoder"), + .type = AVMEDIA_TYPE_DATA, + .id = AV_CODEC_ID_META, + .decode = meta_decode, +};