X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq1enc.c;h=9519d240b546d8a99cecfbccf3ba7f7fe35669cc;hb=96037382210b5c1b0202647ac0ca196ce5de4487;hp=ce46816c16d5806cf2d2f765a924cdefc3027de9;hpb=2ba8301769b770ec96ea8f4c02da78a25c6458fe;p=ffmpeg diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index ce46816c16d..9519d240b54 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -2,25 +2,25 @@ * SVQ1 Encoder * Copyright (C) 2004 Mike Melanson * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * 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. * - * FFmpeg is distributed in the hope that it will be useful, + * 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file libavcodec/svq1enc.c + * @file * Sorenson Vector Quantizer #1 (SVQ1) video codec. * For more information of the SVQ1 algorithm, visit: * http://www.pcisys.net/~melanson/codecs/ @@ -30,6 +30,8 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "h263.h" +#include "internal.h" #include "svq1.h" #include "svq1enc_cb.h" @@ -84,7 +86,7 @@ static void svq1_write_header(SVQ1Context *s, int frame_type) /* frame type */ put_bits(&s->pb, 2, frame_type - 1); - if (frame_type == FF_I_TYPE) { + if (frame_type == AV_PICTURE_TYPE_I) { /* no checksum since frame code is 0x20 */ @@ -93,19 +95,11 @@ static void svq1_write_header(SVQ1Context *s, int frame_type) /* output 5 unknown bits (2 + 2 + 1) */ put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */ - for (i = 0; i < 7; i++) - { - if ((ff_svq1_frame_size_table[i].width == s->frame_width) && - (ff_svq1_frame_size_table[i].height == s->frame_height)) - { - put_bits(&s->pb, 3, i); - break; - } - } + i= ff_match_2uint16(ff_svq1_frame_size_table, FF_ARRAY_ELEMS(ff_svq1_frame_size_table), s->frame_width, s->frame_height); + put_bits(&s->pb, 3, i); if (i == 7) { - put_bits(&s->pb, 3, 7); put_bits(&s->pb, 12, s->frame_width); put_bits(&s->pb, 12, s->frame_height); } @@ -119,10 +113,6 @@ static void svq1_write_header(SVQ1Context *s, int frame_type) #define QUALITY_THRESHOLD 100 #define THRESHOLD_MULTIPLIER 0.6 -#if HAVE_ALTIVEC -#undef vector -#endif - static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ int count, y, x, i, j, split, best_mean, best_score, best_count; int best_vector[6]; @@ -166,7 +156,7 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec } best_count=0; - best_score -= ((block_sum[0]*block_sum[0])>>(level+3)); + best_score -= (int)(((unsigned)block_sum[0]*block_sum[0])>>(level+3)); best_mean= (block_sum[0] + (size>>1)) >> (level+3); if(level<4){ @@ -275,6 +265,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane int block_width, block_height; int level; int threshold[6]; + uint8_t *src = s->scratchbuf + stride * 16; const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT); /* figure out the acceptable level thresholds in advance */ @@ -285,15 +276,15 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane block_width = (width + 15) / 16; block_height = (height + 15) / 16; - if(s->picture.pict_type == FF_P_TYPE){ + if(s->picture.pict_type == AV_PICTURE_TYPE_P){ s->m.avctx= s->avctx; s->m.current_picture_ptr= &s->m.current_picture; s->m.last_picture_ptr = &s->m.last_picture; - s->m.last_picture.data[0]= ref_plane; + s->m.last_picture.f.data[0] = ref_plane; s->m.linesize= - s->m.last_picture.linesize[0]= - s->m.new_picture.linesize[0]= - s->m.current_picture.linesize[0]= stride; + s->m.last_picture.f.linesize[0] = + s->m.new_picture.f.linesize[0] = + s->m.current_picture.f.linesize[0] = stride; s->m.width= width; s->m.height= height; s->m.mb_width= block_width; @@ -323,9 +314,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane s->m.current_picture.mb_mean= (uint8_t *)s->dummy; s->m.current_picture.mb_var= (uint16_t*)s->dummy; s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy; - s->m.current_picture.mb_type= s->dummy; + s->m.current_picture.f.mb_type = s->dummy; - s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2; + s->m.current_picture.f.motion_val[0] = s->motion_val8[plane] + 2; s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1; s->m.dsp= s->dsp; //move ff_init_me(&s->m); @@ -333,9 +324,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane s->m.me.dia_size= s->avctx->dia_size; s->m.first_slice_line=1; for (y = 0; y < block_height; y++) { - uint8_t src[stride*16]; - - s->m.new_picture.data[0]= src - y*16*stride; //ugly + s->m.new_picture.f.data[0] = src - y*16*stride; //ugly s->m.mb_y= y; for(i=0; i<16 && i + 16*ym.first_slice_line=1; for (y = 0; y < block_height; y++) { - uint8_t src[stride*16]; - for(i=0; i<16 && i + 16*ym); ff_update_block_index(&s->m); - if(s->picture.pict_type == FF_I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ + if(s->picture.pict_type == AV_PICTURE_TYPE_I || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ for(i=0; i<6; i++){ init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); } - if(s->picture.pict_type == FF_P_TYPE){ + if(s->picture.pict_type == AV_PICTURE_TYPE_P){ const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); score[0]= vlc[1]*lambda; @@ -410,12 +397,12 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane best=0; - if(s->picture.pict_type == FF_P_TYPE){ + if(s->picture.pict_type == AV_PICTURE_TYPE_P){ const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; - motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); + motion_ptr= ff_h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ for(i=0; i<6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); @@ -470,7 +457,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane s->rd_total += score[best]; for(i=5; i>=0; i--){ - ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); + avpriv_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); } if(best==0){ s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16); @@ -485,8 +472,8 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) { SVQ1Context * const s = avctx->priv_data; - dsputil_init(&s->dsp, avctx); - avctx->coded_frame= (AVFrame*)&s->picture; + ff_dsputil_init(&s->dsp, avctx); + avctx->coded_frame = &s->picture; s->frame_width = avctx->width; s->frame_height = avctx->height; @@ -505,19 +492,24 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); - h263_encode_init(&s->m); //mv_penalty + ff_h263_encode_init(&s->m); //mv_penalty return 0; } -static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) +static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *pict, int *got_packet) { SVQ1Context * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; AVFrame temp; - int i; + int i, ret; + + if (!pkt->data && + (ret = av_new_packet(pkt, s->y_block_width*s->y_block_height*MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE) < 0)) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); + return ret; + } if(avctx->pix_fmt != PIX_FMT_YUV410P){ av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); @@ -527,18 +519,18 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, if(!s->current_picture.data[0]){ avctx->get_buffer(avctx, &s->current_picture); avctx->get_buffer(avctx, &s->last_picture); - s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16); + s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); } temp= s->current_picture; s->current_picture= s->last_picture; s->last_picture= temp; - init_put_bits(&s->pb, buf, buf_size); + init_put_bits(&s->pb, pkt->data, pkt->size); *p = *pict; - p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? FF_P_TYPE : FF_I_TYPE; - p->key_frame = p->pict_type == FF_I_TYPE; + p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + p->key_frame = p->pict_type == AV_PICTURE_TYPE_I; svq1_write_header(s, p->pict_type); for(i=0; i<3; i++){ @@ -549,13 +541,18 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, return -1; } -// align_put_bits(&s->pb); +// avpriv_align_put_bits(&s->pb); while(put_bits_count(&s->pb) & 31) put_bits(&s->pb, 1, 0); flush_put_bits(&s->pb); - return put_bits_count(&s->pb) / 8; + pkt->size = put_bits_count(&s->pb) / 8; + if (p->pict_type == AV_PICTURE_TYPE_I) + pkt->flags |= AV_PKT_FLAG_KEY; + *got_packet = 1; + + return 0; } static av_cold int svq1_encode_end(AVCodecContext *avctx) @@ -581,14 +578,14 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx) } -AVCodec svq1_encoder = { - "svq1", - CODEC_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(SVQ1Context), - svq1_encode_init, - svq1_encode_frame, - svq1_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1"), +AVCodec ff_svq1_encoder = { + .name = "svq1", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_SVQ1, + .priv_data_size = sizeof(SVQ1Context), + .init = svq1_encode_init, + .encode2 = svq1_encode_frame, + .close = svq1_encode_end, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV410P, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), };