From patchwork Tue Nov 8 12:57:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenyu Wang X-Patchwork-Id: 1340 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.90.1 with SMTP id o1csp1671515vsb; Tue, 8 Nov 2016 04:57:40 -0800 (PST) X-Received: by 10.28.232.213 with SMTP id f82mr14003272wmi.85.1478609860504; Tue, 08 Nov 2016 04:57:40 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id rk19si35402814wjb.69.2016.11.08.04.57.39; Tue, 08 Nov 2016 04:57:40 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5E42C689C52; Tue, 8 Nov 2016 14:57:33 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from pku.edu.cn (mx9.pku.edu.cn [162.105.129.172]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 399A4689A67 for ; Tue, 8 Nov 2016 14:57:25 +0200 (EET) Received: from localhost.localdomain (unknown [219.223.194.133]) by mailfront02 (Coremail) with SMTP id 8oFpogDnj8+2yyFYVg0UAA--.49694S2; Tue, 08 Nov 2016 20:57:26 +0800 (CST) From: Zhenyu Wang To: ffmpeg-devel@ffmpeg.org Date: Tue, 8 Nov 2016 20:57:13 +0800 Message-Id: <1478609833-15193-1-git-send-email-wangzhenyu@pkusz.edu.cn> X-Mailer: git-send-email 2.7.4 X-CM-TRANSID: 8oFpogDnj8+2yyFYVg0UAA--.49694S2 X-Coremail-Antispam: 1UD129KBjvAXoW3KFy8trW7Xw1DGr1rWw4rXwb_yoW8CFyDXo WUZ3Wjqw1rZ343u3Wvkr1DWr1YgFn0qrW2yws2vayjyay8ua45Gryjy345Jay3CrWrtFW3 AFW2qrW7Xa1kKrs3n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYI7CY07I20VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAF z4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0Y4vE2Ix0cI 8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwA2z4x0Y4vE x4A2jsIE14v26F4UJVW0owA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1le2I262IYc4 CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x 0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK67AK6ryUMxAIw28IcxkI7VAK I48JMxAIw28IcVCjz48v1sIEY20_Gw1UJr1UMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I 0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWU XVWUAwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcV CY1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Wr1j6rW3Jr1lIxAIcVC2z280 aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyT uYvjfU5rWrDUUUU X-CM-SenderInfo: pzdqw65khq5346sn32v2ohv3gofq/ Subject: [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. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Zhenyu Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- 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 + * + * 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 #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') },