Mercurial > mplayer.hg
view libmpcodecs/ad_ffmpeg.c @ 20874:b6d87b58754f
Partial fix for semitransparent glyph outlines.
This fix removes semitransparent area (less then pixel width) between glyph and
it's outline. Instead, it makes them overlap a little. It usually looks much
better this way.
Complete fix seems impossible with the current output format (single color
alpha bitmaps). The right way is to blend both glyph and outline into one
bitmap so that 2 pixels with 50% transparency produce a fully solid one.
This requires RGBA bitmap output from libass.
author | eugeni |
---|---|
date | Mon, 13 Nov 2006 16:35:15 +0000 |
parents | 5d9f47834495 |
children | 1767c271d710 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "config.h" #include "mp_msg.h" #include "help_mp.h" #include "ad_internal.h" #include "bswap.h" static ad_info_t info = { "FFmpeg/libavcodec audio decoders", "ffmpeg", "Nick Kurshev", "ffmpeg.sf.net", "" }; LIBAD_EXTERN(ffmpeg) #define assert(x) #ifdef USE_LIBAVCODEC_SO #include <ffmpeg/avcodec.h> #else #include "avcodec.h" #endif extern int avcodec_inited; static int preinit(sh_audio_t *sh) { sh->audio_out_minsize=AVCODEC_MAX_AUDIO_FRAME_SIZE; return 1; } static int init(sh_audio_t *sh_audio) { int x; AVCodecContext *lavc_context; AVCodec *lavc_codec; mp_msg(MSGT_DECAUDIO,MSGL_V,"FFmpeg's libavcodec audio codec\n"); if(!avcodec_inited){ avcodec_init(); avcodec_register_all(); avcodec_inited=1; } lavc_codec = (AVCodec *)avcodec_find_decoder_by_name(sh_audio->codec->dll); if(!lavc_codec){ mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_MissingLAVCcodec,sh_audio->codec->dll); return 0; } lavc_context = avcodec_alloc_context(); sh_audio->context=lavc_context; if(sh_audio->wf){ lavc_context->channels = sh_audio->wf->nChannels; lavc_context->sample_rate = sh_audio->wf->nSamplesPerSec; lavc_context->bit_rate = sh_audio->wf->nAvgBytesPerSec * 8; lavc_context->block_align = sh_audio->wf->nBlockAlign; lavc_context->bits_per_sample = sh_audio->wf->wBitsPerSample; } lavc_context->codec_tag = sh_audio->format; //FOURCC lavc_context->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi /* alloc extra data */ if (sh_audio->wf && sh_audio->wf->cbSize > 0) { lavc_context->extradata = av_mallocz(sh_audio->wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE); lavc_context->extradata_size = sh_audio->wf->cbSize; memcpy(lavc_context->extradata, (char *)sh_audio->wf + sizeof(WAVEFORMATEX), lavc_context->extradata_size); } // for QDM2 if (sh_audio->codecdata_len && sh_audio->codecdata && !lavc_context->extradata) { lavc_context->extradata = av_malloc(sh_audio->codecdata_len); lavc_context->extradata_size = sh_audio->codecdata_len; memcpy(lavc_context->extradata, (char *)sh_audio->codecdata, lavc_context->extradata_size); } /* open it */ if (avcodec_open(lavc_context, lavc_codec) < 0) { mp_msg(MSGT_DECAUDIO,MSGL_ERR, MSGTR_CantOpenCodec); return 0; } mp_msg(MSGT_DECAUDIO,MSGL_V,"INFO: libavcodec init OK!\n"); // printf("\nFOURCC: 0x%X\n",sh_audio->format); if(sh_audio->format==0x3343414D){ // MACE 3:1 sh_audio->ds->ss_div = 2*3; // 1 samples/packet sh_audio->ds->ss_mul = 2*sh_audio->wf->nChannels; // 1 byte*ch/packet } else if(sh_audio->format==0x3643414D){ // MACE 6:1 sh_audio->ds->ss_div = 2*6; // 1 samples/packet sh_audio->ds->ss_mul = 2*sh_audio->wf->nChannels; // 1 byte*ch/packet } // Decode at least 1 byte: (to get header filled) x=decode_audio(sh_audio,sh_audio->a_buffer,1,sh_audio->a_buffer_size); if(x>0) sh_audio->a_buffer_len=x; sh_audio->channels=lavc_context->channels; sh_audio->samplerate=lavc_context->sample_rate; sh_audio->i_bps=lavc_context->bit_rate/8; if(sh_audio->wf){ // If the decoder uses the wrong number of channels all is lost anyway. // sh_audio->channels=sh_audio->wf->nChannels; if (sh_audio->wf->nSamplesPerSec) sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; if (sh_audio->wf->nAvgBytesPerSec) sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; } sh_audio->samplesize=2; return 1; } static void uninit(sh_audio_t *sh) { AVCodecContext *lavc_context = sh->context; if (avcodec_close(lavc_context) < 0) mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantCloseCodec); av_freep(&lavc_context->extradata); av_freep(&lavc_context); } static int control(sh_audio_t *sh,int cmd,void* arg, ...) { AVCodecContext *lavc_context = sh->context; switch(cmd){ case ADCTRL_RESYNC_STREAM: avcodec_flush_buffers(lavc_context); return CONTROL_TRUE; } return CONTROL_UNKNOWN; } static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { unsigned char *start=NULL; int y,len=-1; while(len<minlen){ int len2=0; double pts; int x=ds_get_packet_pts(sh_audio->ds,&start, &pts); if(x<=0) break; // error if (pts != MP_NOPTS_VALUE) { sh_audio->pts = pts; sh_audio->pts_bytes = 0; } y=avcodec_decode_audio(sh_audio->context,(int16_t*)buf,&len2,start,x); //printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout); if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; } if(y<x) sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!) if(len2>0){ //len=len2;break; if(len<0) len=len2; else len+=len2; buf+=len2; sh_audio->pts_bytes += len2; } mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d \n",y,len2); } return len; }