This is heavily based on MPEG-2 encoder, of course. --- Changelog | 1 + doc/general.texi | 2 +- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/mpegutils.h | 1 + libavcodec/mpegvideo.h | 3 +++ libavcodec/mpegvideo_enc.c | 52 +++++++++++++++++++++++++++++++++++--- libavcodec/version.h | 2 +- 8 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/Changelog b/Changelog index 49fc260458..8f3dcbec87 100644 --- a/Changelog +++ b/Changelog @@ -7,6 +7,7 @@ version <next>: - PGX decoder - chromanr video filter - VDPAU accelerated HEVC 10/12bit decoding +- SpeedHQ encoder version 4.3: diff --git a/doc/general.texi b/doc/general.texi index 53d556c56c..7ab1c61267 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -971,7 +971,7 @@ following image formats are supported: @item MPEG-4 part 2 Microsoft variant version 1 @tab @tab X @item MPEG-4 part 2 Microsoft variant version 2 @tab X @tab X @item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X -@item Newtek SpeedHQ @tab @tab X +@item Newtek SpeedHQ @tab X @tab X @item Nintendo Gamecube THP video @tab @tab X @item NotchLC @tab @tab X @item NuppelVideo/RTjpeg @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 18353da549..52445130f4 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -614,6 +614,7 @@ OBJS-$(CONFIG_SONIC_DECODER) += sonic.o OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o +OBJS-$(CONFIG_SPEEDHQ_ENCODER) += speedhq.o mpeg12data.o speedhqenc.o OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o OBJS-$(CONFIG_SRGC_DECODER) += mscc.o OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index a5048290f7..b542910303 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -290,6 +290,7 @@ extern AVCodec ff_snow_encoder; extern AVCodec ff_snow_decoder; extern AVCodec ff_sp5x_decoder; extern AVCodec ff_speedhq_decoder; +extern AVCodec ff_speedhq_encoder; extern AVCodec ff_srgc_decoder; extern AVCodec ff_sunrast_encoder; extern AVCodec ff_sunrast_decoder; diff --git a/libavcodec/mpegutils.h b/libavcodec/mpegutils.h index 1ed21c19be..81f0b73bb1 100644 --- a/libavcodec/mpegutils.h +++ b/libavcodec/mpegutils.h @@ -125,6 +125,7 @@ enum OutputFormat { FMT_H261, FMT_H263, FMT_MJPEG, + FMT_SPEEDHQ, }; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 29e692f245..974c71b6bd 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -444,6 +444,9 @@ typedef struct MpegEncContext { int inter_intra_pred; int mspel; + /* SpeedHQ specific */ + int slice_start; + /* decompression specific */ GetBitContext gb; diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index c3ef40556a..221079452c 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -51,6 +51,7 @@ #include "mathops.h" #include "mpegutils.h" #include "mjpegenc.h" +#include "speedhqenc.h" #include "msmpeg4.h" #include "pixblockdsp.h" #include "qpeldsp.h" @@ -326,6 +327,15 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } break; + case AV_CODEC_ID_SPEEDHQ: + if (avctx->pix_fmt != AV_PIX_FMT_YUV420P && + avctx->pix_fmt != AV_PIX_FMT_YUV422P && + avctx->pix_fmt != AV_PIX_FMT_YUV444P) { + av_log(avctx, AV_LOG_ERROR, + "only YUV420/YUV422/YUV444 are supported (no alpha support yet)\n"); + return AVERROR(EINVAL); + } + break; default: if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) { av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); @@ -732,7 +742,7 @@ FF_ENABLE_DEPRECATION_WARNINGS //return -1; } - if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id==AV_CODEC_ID_AMV) { + if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id==AV_CODEC_ID_AMV || s->codec_id == AV_CODEC_ID_SPEEDHQ) { // (a + x * 3 / 8) / x s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3); s->inter_quant_bias = 0; @@ -783,6 +793,16 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->delay = 0; s->low_delay = 1; break; + case AV_CODEC_ID_SPEEDHQ: + s->out_format = FMT_SPEEDHQ; + s->intra_only = 1; /* force intra only for SHQ */ + if (!CONFIG_SPEEDHQ_ENCODER) + return AVERROR_ENCODER_NOT_FOUND; + if ((ret = ff_speedhq_encode_init(s)) < 0) + return ret; + avctx->delay = 0; + s->low_delay = 1; + break; case AV_CODEC_ID_H261: if (!CONFIG_H261_ENCODER) return AVERROR_ENCODER_NOT_FOUND; @@ -997,6 +1017,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) { s->intra_matrix[j] = s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; + } else if (CONFIG_SPEEDHQ_ENCODER && s->codec_id == AV_CODEC_ID_SPEEDHQ) { + s->intra_matrix[j] = + s->inter_matrix[j] = ff_mpeg1_default_intra_matrix[i]; } else { /* MPEG-1/2 */ s->chroma_intra_matrix[j] = @@ -2562,6 +2585,10 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, if (CONFIG_MJPEG_ENCODER) ff_mjpeg_encode_mb(s, s->block); break; + case AV_CODEC_ID_SPEEDHQ: + if (CONFIG_SPEEDHQ_ENCODER) + ff_speedhq_encode_mb(s, s->block); + break; default: av_assert1(0); } @@ -2816,6 +2843,8 @@ static void write_slice_end(MpegEncContext *s){ ff_mpeg4_stuffing(&s->pb); }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ ff_mjpeg_encode_stuffing(s); + }else if(CONFIG_SPEEDHQ_ENCODER && s->out_format == FMT_SPEEDHQ){ + ff_speedhq_end_slice(s); } avpriv_align_put_bits(&s->pb); @@ -2906,7 +2935,7 @@ int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t s static int encode_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; - int mb_x, mb_y; + int mb_x, mb_y, mb_y_order; int chr_h= 16>>s->chroma_y_shift; int i, j; MpegEncContext best_s = { 0 }, backup_s; @@ -2967,7 +2996,16 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->resync_mb_y=0; s->first_slice_line = 1; s->ptr_lastgob = s->pb.buf; - for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { + for(mb_y_order= s->start_mb_y; mb_y_order < s->end_mb_y; mb_y_order++) { + if (s->codec_id == AV_CODEC_ID_SPEEDHQ) { + int first_in_slice; + mb_y = ff_speedhq_mb_y_order_to_mb(mb_y_order, s->mb_height, &first_in_slice); + if (first_in_slice && mb_y_order != s->start_mb_y) + ff_speedhq_end_slice(s); + s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 1024 << s->intra_dc_precision; + } else { + mb_y = mb_y_order; + } s->mb_x=0; s->mb_y= mb_y; @@ -3855,6 +3893,10 @@ static int encode_picture(MpegEncContext *s, int picture_number) s->chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1); s->qscale= 8; } + if (s->out_format == FMT_SPEEDHQ) { + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg2_dc_scale_table[3]; + } //FIXME var duplication s->current_picture_ptr->f->key_frame = @@ -3873,6 +3915,10 @@ static int encode_picture(MpegEncContext *s, int picture_number) ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, s->pred, s->intra_matrix, s->chroma_intra_matrix); break; + case FMT_SPEEDHQ: + if (CONFIG_SPEEDHQ_ENCODER) + ff_speedhq_encode_picture_header(s); + break; case FMT_H261: if (CONFIG_H261_ENCODER) ff_h261_encode_picture_header(s, picture_number); diff --git a/libavcodec/version.h b/libavcodec/version.h index e75891d463..3e34af5348 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 58 #define LIBAVCODEC_VERSION_MINOR 95 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.27.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".