[FFmpeg-devel] [PATCH] Add decoding support for the second generation IEEE 1857 video coding standard(AVS2) using uavs2d library(git clones https://github.com/nelvtpkusz/uavs2d.git uavs2d). Support AVS2 in mpegts, flv and mp4 format.
Zhenyu Wang
wangzhenyu at pkusz.edu.cn
Tue Nov 8 14:57:13 EET 2016
---
configure | 4 +
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 2 +
libavcodec/avcodec.h | 1 +
libavcodec/cavs_parser.c | 9 ++
libavcodec/codec_desc.c | 7 ++
libavcodec/libuavs2d.c | 218 +++++++++++++++++++++++++++++++++++++++++++++
libavformat/allformats.c | 1 +
libavformat/cavsvideodec.c | 47 ++++++++++
libavformat/flv.h | 1 +
libavformat/flvdec.c | 5 ++
libavformat/isom.c | 2 +
libavformat/mpeg.h | 1 +
libavformat/mpegts.c | 1 +
libavformat/mpegts.h | 1 +
libavformat/rawenc.c | 13 +++
libavformat/riff.c | 1 +
17 files changed, 315 insertions(+)
create mode 100644 libavcodec/libuavs2d.c
diff --git a/configure b/configure
index 87b06f1..76f00ed 100755
--- a/configure
+++ b/configure
@@ -269,6 +269,7 @@ External library support:
--enable-libx264 enable H.264 encoding via x264 [no]
--enable-libx265 enable HEVC encoding via x265 [no]
--enable-libxavs enable AVS encoding via xavs [no]
+ --enable-libuavs2d enable AVS2 decoding via uavs2d [no]
--enable-libxcb enable X11 grabbing using XCB [autodetect]
--enable-libxcb-shm enable X11 grabbing shm communication [autodetect]
--enable-libxcb-xfixes enable X11 grabbing mouse rendering [autodetect]
@@ -1535,6 +1536,7 @@ EXTERNAL_LIBRARY_LIST="
libx264
libx265
libxavs
+ libuavs2d
libxcb
libxcb_shm
libxcb_shape
@@ -2833,6 +2835,7 @@ libx264rgb_encoder_deps="libx264 x264_csp_bgr"
libx264rgb_encoder_select="libx264_encoder"
libx265_encoder_deps="libx265"
libxavs_encoder_deps="libxavs"
+libuavs2d_decoder_deps="libuavs2d"
libxvid_encoder_deps="libxvid"
libzvbi_teletext_decoder_deps="libzvbi"
videotoolbox_deps="VideoToolbox_VideoToolbox_h"
@@ -5787,6 +5790,7 @@ enabled libx265 && require_pkg_config x265 x265.h x265_api_get &&
{ check_cpp_condition x265.h "X265_BUILD >= 68" ||
die "ERROR: libx265 version must be >= 68."; }
enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs
+enabled libuavs2d && require libuavs2d uavs2d.h uavs2d_lib_decode -luavs2d
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
enabled libzimg && require_pkg_config zimg zimg.h zimg_get_api_version
enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f1d5bf1..ca9282d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -910,6 +910,7 @@ OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
+OBJS-$(CONFIG_LIBUAVS2D_DECODER) += libuavs2d.o
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index ada9481..9afa3e8 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -622,6 +622,7 @@ void avcodec_register_all(void)
REGISTER_ENCODER(LIBX264RGB, libx264rgb);
REGISTER_ENCODER(LIBX265, libx265);
REGISTER_ENCODER(LIBXAVS, libxavs);
+ REGISTER_DECODER(LIBUAVS2D, libuavs2d);
REGISTER_ENCODER(LIBXVID, libxvid);
REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext);
@@ -670,6 +671,7 @@ void avcodec_register_all(void)
REGISTER_PARSER(ADX, adx);
REGISTER_PARSER(BMP, bmp);
REGISTER_PARSER(CAVSVIDEO, cavsvideo);
+ REGISTER_PARSER(CAVS2VIDEO, cavs2video);
REGISTER_PARSER(COOK, cook);
REGISTER_PARSER(DCA, dca);
REGISTER_PARSER(DIRAC, dirac);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 211112f..9c0a4bf 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -282,6 +282,7 @@ enum AVCodecID {
AV_CODEC_ID_KMVC,
AV_CODEC_ID_FLASHSV,
AV_CODEC_ID_CAVS,
+ AV_CODEC_ID_CAVS2,
AV_CODEC_ID_JPEG2000,
AV_CODEC_ID_VMNC,
AV_CODEC_ID_VP5,
diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c
index 6067a39..a2cef8b 100644
--- a/libavcodec/cavs_parser.c
+++ b/libavcodec/cavs_parser.c
@@ -104,3 +104,12 @@ AVCodecParser ff_cavsvideo_parser = {
.parser_close = ff_parse_close,
.split = ff_mpeg4video_split,
};
+
+AVCodecParser ff_cavs2video_parser = {
+ .codec_ids = { AV_CODEC_ID_CAVS2 },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = cavsvideo_parse,
+ .parser_close = ff_parse_close,
+ .split = ff_mpeg4video_split,
+};
+
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 9dbe2dc..c510a4d 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -601,6 +601,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER,
},
{
+ .id = AV_CODEC_ID_CAVS2,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "cavs2",
+ .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS2 (Audio Video Standard)"),
+ .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER,
+ },
+ {
.id = AV_CODEC_ID_JPEG2000,
.type = AVMEDIA_TYPE_VIDEO,
.name = "jpeg2000",
diff --git a/libavcodec/libuavs2d.c b/libavcodec/libuavs2d.c
new file mode 100644
index 0000000..0e80afd
--- /dev/null
+++ b/libavcodec/libuavs2d.c
@@ -0,0 +1,218 @@
+/*
+ * AVS2 decoding using the uavs2d library
+ * Copyright (C) 2016 uavs2d project,
+ * National Engineering Laboratory for Video Technology(Shenzhen),
+ * Digital Media R&D Center at Peking University Shenzhen Graduate School, China
+ *
+ * Z.Y. Wang <wangzhenyu at pkusz.edu.cn>
+ *
+ * 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/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/avutil.h"
+#include "avcodec.h"
+#include "uavs2d.h"
+#include "libavutil/imgutils.h"
+#include "internal.h"
+
+
+const enum AVPictureType IMGTYPE[8] = {
+ AV_PICTURE_TYPE_NONE,
+ AV_PICTURE_TYPE_I,
+ AV_PICTURE_TYPE_NONE,
+ AV_PICTURE_TYPE_NONE,
+ AV_PICTURE_TYPE_NONE,
+ AV_PICTURE_TYPE_P,
+ AV_PICTURE_TYPE_P,
+ AV_PICTURE_TYPE_B
+};
+
+typedef struct UAVS2DContext {
+ AVCodecContext *avctx;
+ void *dec_handle;
+ avs2_frame_t dec_frame;
+ int got_seqhdr;
+} UAVS2DContext;
+
+
+static int find_next_start_code(const unsigned char *bs_data, int bs_len, int *left)
+{
+ const unsigned char *data_ptr = bs_data + 4;
+ int count = bs_len - 4;
+
+ while (count >= 4 &&
+ ((*(unsigned int *)data_ptr) != 0xB6010000) && /* P/B picture */
+ ((*(unsigned int *)data_ptr) != 0xB3010000) && /* I picture */
+ ((*(unsigned int *)data_ptr) != 0xB0010000) && /* sequence header */
+ ((*(unsigned int *)data_ptr) != 0xB1010000)) { /* sequence end */
+ data_ptr++;
+ count--;
+ }
+
+ if (count >= 4) {
+ *left = count;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int ff_uavs2d_init(AVCodecContext *avctx)
+{
+ UAVS2DContext *h = avctx->priv_data;
+ h->dec_handle = uavs2d_lib_create(1, 1);
+ h->dec_frame.i_output_type = AVS2_OUT_I420;
+ h->got_seqhdr = 0;
+
+ avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
+ return 0;
+}
+
+static int ff_uavs2d_end(AVCodecContext *avctx)
+{
+ UAVS2DContext *h = avctx->priv_data;
+ uavs2d_lib_destroy(h->dec_handle);
+ h->got_seqhdr = 0;
+ return 0;
+}
+
+static void uavs2d_flush(AVCodecContext * avctx)
+{
+ UAVS2DContext *h = avctx->priv_data;
+ h->dec_frame.bs_len = -1;
+
+ do {
+ uavs2d_lib_flush(h->dec_handle, &h->dec_frame);
+ } while (h->dec_frame.dec_stats == AVS2_TYPE_DECODED);
+
+ h->got_seqhdr = 0;
+
+ uavs2d_lib_destroy(h->dec_handle);
+ h->got_seqhdr = 0;
+ h->dec_handle = uavs2d_lib_create(1, 1);
+ h->dec_frame.i_output_type = AVS2_OUT_I420;
+}
+
+static int uavs2d_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
+{
+ UAVS2DContext *h = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ const uint8_t *buf_end;
+ const uint8_t *buf_ptr;
+ AVFrame *frm = (AVFrame*)data;
+ int left_bytes;
+ int ret, finish = 0;
+
+ if (buf_size == 0) {
+ if (h->got_seqhdr) {
+ if (frm->data[0] == NULL && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
+ return ret;
+ }
+ h->dec_frame.bs_len = -1;
+ h->dec_frame.p_buf_y = frm->data[0];
+ h->dec_frame.p_buf_u = frm->data[1];
+ h->dec_frame.p_buf_v = frm->data[2];
+ h->dec_frame.i_stride = frm->linesize[0];
+ h->dec_frame.i_stridec = frm->linesize[1];
+ uavs2d_lib_flush(h->dec_handle, &h->dec_frame);
+ if (h->dec_frame.dec_stats == AVS2_TYPE_DECODED) {
+ *got_frame = 1;
+ frm->pts = h->dec_frame.pts;
+ frm->pict_type = IMGTYPE[h->dec_frame.frm_type];
+ }
+ }
+ return 0;
+ }
+
+ buf_ptr = buf;
+ buf_end = buf + buf_size;
+
+ while (finish == 0) {
+ if (find_next_start_code(buf_ptr, buf_end - buf_ptr, &left_bytes)) {
+ h->dec_frame.bs_len = buf_end - buf_ptr - left_bytes;
+ } else {
+ h->dec_frame.bs_len = buf_end - buf_ptr;
+ finish = 1;
+ }
+ h->dec_frame.bs_buf = (uint8_t*)buf_ptr;
+ h->dec_frame.pts = avpkt->pts;
+
+ buf_ptr += h->dec_frame.bs_len;
+
+ if (h->got_seqhdr && frm->data[0]== NULL && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
+ return ret;
+ }
+ h->dec_frame.p_buf_y = frm->data[0];
+ h->dec_frame.p_buf_u = frm->data[1];
+ h->dec_frame.p_buf_v = frm->data[2];
+ h->dec_frame.i_stride = frm->linesize[0];
+ h->dec_frame.i_stridec = frm->linesize[1];
+
+ uavs2d_lib_decode(h->dec_handle, &h->dec_frame);
+
+ switch (h->dec_frame.dec_stats) {
+ case AVS2_TYPE_DECODED: /* decode one frame */
+ *got_frame = 1;
+ finish = 1;
+ frm->pts = h->dec_frame.pts;
+ frm->pict_type = IMGTYPE[h->dec_frame.frm_type];
+ break;
+ case AVS2_TYPE_ERROR: /* error, current or next frame was not decoded */
+ av_log(h->avctx, AV_LOG_WARNING, "decode error\n");
+ break;
+ case AVS2_TYPE_DROP: /* error, current or next frame was not decoded */
+ av_log(h->avctx, AV_LOG_WARNING, "DROP non-RA frame\n");
+ break;
+ case AVS2_TYPE_SEQ: /* sequence header was decoded */
+ if (avctx->width != h->dec_frame.info.img_width || avctx->height != h->dec_frame.info.img_height) {
+ static const int avs2_fps_num[8] = { 240000, 24, 25, 30000, 30, 50, 60000, 60 };
+ static const int avs2_fps_den[8] = { 1001, 1, 1, 1001, 1, 1, 1001, 1 };
+ av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", avctx->width, avctx->height, h->dec_frame.info.img_width, h->dec_frame.info.img_height);
+ ret = ff_set_dimensions(avctx, h->dec_frame.info.img_width, h->dec_frame.info.img_height);
+
+ if (ret < 0) {
+ return ret;
+ }
+ avctx->framerate.num = avs2_fps_num[h->dec_frame.info.frame_rate_code];
+ avctx->framerate.den = avs2_fps_den[h->dec_frame.info.frame_rate_code];
+ }
+ h->got_seqhdr = 1;
+ }
+ }
+
+ return buf_ptr - buf;
+}
+
+AVCodec ff_libuavs2d_decoder = {
+ .name = "uavs2d",
+ .long_name = NULL_IF_CONFIG_SMALL("Decoder for Chinese AVS2"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_CAVS2,
+ .priv_data_size = sizeof(UAVS2DContext),
+ .init = ff_uavs2d_init,
+ .close = ff_uavs2d_end,
+ .decode = uavs2d_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .flush = uavs2d_flush,
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE },
+};
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 6a216ef..7f7a755 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -95,6 +95,7 @@ void av_register_all(void)
REGISTER_DEMUXER (C93, c93);
REGISTER_MUXDEMUX(CAF, caf);
REGISTER_MUXDEMUX(CAVSVIDEO, cavsvideo);
+ REGISTER_MUXDEMUX(CAVS2VIDEO, cavs2video);
REGISTER_DEMUXER (CDG, cdg);
REGISTER_DEMUXER (CDXL, cdxl);
REGISTER_DEMUXER (CINE, cine);
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index b4da58e..8d6325d 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <ctype.h>
#include "avformat.h"
#include "rawdec.h"
#include "libavcodec/internal.h"
@@ -66,4 +67,50 @@ static int cavsvideo_probe(AVProbeData *p)
return 0;
}
+static int cavs2video_probe(AVProbeData *p)
+{
+ uint32_t code= -1;
+ int pic=0, seq=0, slice_pos = 0;
+ const uint8_t *ptr = p->buf, *end = p->buf + p->buf_size;
+ int ret = 0;
+
+ while (ptr < end) {
+ ptr = avpriv_find_start_code(ptr, end, &code);
+ if ((code & 0xffffff00) == 0x100) {
+ if(code < CAVS_SEQ_START_CODE) {
+ /* slices have to be consecutive */
+ if(code < slice_pos)
+ return 0;
+ slice_pos = code;
+ } else {
+ slice_pos = 0;
+ }
+ if (code == CAVS_SEQ_START_CODE) {
+ seq++;
+ /* check for the only currently supported profile */
+ if (*ptr != CAVS_PROFILE_JIZHUN)
+ return 0;
+ } else if ((code == CAVS_PIC_I_START_CODE) ||
+ (code == CAVS_PIC_PB_START_CODE)) {
+ pic++;
+ } else if ((code == CAVS_UNDEF_START_CODE) ||
+ (code > CAVS_VIDEO_EDIT_CODE)) {
+ return 0;
+ }
+ }
+ }
+ if(seq && pic) {
+ const char *str = p->filename + strlen(p->filename) - 5;
+ if (tolower(str[0]) == 'c' && tolower(str[1]) == 'a' && tolower(str[2]) == 'v' &&tolower(str[3]) == 's' && str[4] == '2') {
+ ret = AVPROBE_SCORE_EXTENSION+2;
+ }
+ }
+ return ret;
+}
+
+
+
FF_DEF_RAWVIDEO_DEMUXER(cavsvideo, "raw Chinese AVS (Audio Video Standard)", cavsvideo_probe, NULL, AV_CODEC_ID_CAVS)
+
+FF_DEF_RAWVIDEO_DEMUXER(cavs2video, "raw Chinese AVS2 (Audio Video Standard)", cavs2video_probe, "cavs2", AV_CODEC_ID_CAVS2)
+
diff --git a/libavformat/flv.h b/libavformat/flv.h
index df5ce3d..78ff1b3 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -109,6 +109,7 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_CAVS2 = 10,
};
enum {
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index e53c345..e85fcbc 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -281,6 +281,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_CAVS2:
+ return vpar->codec_id == AV_CODEC_ID_CAVS2;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -325,6 +327,9 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
case FLV_CODECID_MPEG4:
par->codec_id = AV_CODEC_ID_MPEG4;
return 3;
+ case FLV_CODECID_CAVS2:
+ par->codec_id = AV_CODEC_ID_CAVS2;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 1fa46bd..b0bb8c3 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -36,6 +36,7 @@ const AVCodecTag ff_mp4_obj_type[] = {
{ AV_CODEC_ID_MPEG4 , 0x20 },
{ AV_CODEC_ID_H264 , 0x21 },
{ AV_CODEC_ID_HEVC , 0x23 },
+ { AV_CODEC_ID_CAVS2 , 0x24 },
{ AV_CODEC_ID_AAC , 0x40 },
{ AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */
{ AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG-2 Main */
@@ -244,6 +245,7 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
{ AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */
{ AV_CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') },
+ { AV_CODEC_ID_CAVS2, MKTAG('c', 'a', 'v', '2') },
{ AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index 617e36c..faa875e 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -56,6 +56,7 @@
#define STREAM_TYPE_VIDEO_MPEG4 0x10
#define STREAM_TYPE_VIDEO_H264 0x1b
#define STREAM_TYPE_VIDEO_CAVS 0x42
+#define STREAM_TYPE_VIDEO_CAVS2 0x52
#define STREAM_TYPE_AUDIO_AC3 0x81
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index fad10c6..2dbd460 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -705,6 +705,7 @@ static const StreamType ISO_types[] = {
{ 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 },
{ 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC },
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS },
+ { 0x52, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS2 },
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
{ 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
{ 0 },
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 272e2be..d0f7033 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -55,6 +55,7 @@
#define STREAM_TYPE_VIDEO_H264 0x1b
#define STREAM_TYPE_VIDEO_HEVC 0x24
#define STREAM_TYPE_VIDEO_CAVS 0x42
+#define STREAM_TYPE_VIDEO_CAVS2 0x52
#define STREAM_TYPE_VIDEO_VC1 0xea
#define STREAM_TYPE_VIDEO_DIRAC 0xd1
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 730e99a..bd0d415 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -104,6 +104,19 @@ AVOutputFormat ff_cavsvideo_muxer = {
};
#endif
+#if CONFIG_CAVS2VIDEO_MUXER
+AVOutputFormat ff_cavs2video_muxer = {
+ .name = "cavs2video",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Chinese AVS2 (Audio Video Standard) video"),
+ .extensions = "cavs2",
+ .audio_codec = AV_CODEC_ID_NONE,
+ .video_codec = AV_CODEC_ID_CAVS2,
+ .write_header = force_one_stream,
+ .write_packet = ff_raw_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
+};
+#endif
+
#if CONFIG_DATA_MUXER
AVOutputFormat ff_data_muxer = {
.name = "data",
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 3c5a37c..ec2d1cf 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -362,6 +362,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ AV_CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') },
{ AV_CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') },
{ AV_CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') },
+ { AV_CODEC_ID_CAVS2, MKTAG('C', 'A', 'V', '2') },
{ AV_CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') },
{ AV_CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
{ AV_CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'C') },
--
2.7.4
More information about the ffmpeg-devel
mailing list