static int af_open(af_instance_t* af){ af_ac3enc_t *s = calloc(1,sizeof(af_ac3enc_t)); int pending_space = 2 * AC3_MAX_CHANNELS * AC3_FRAME_SIZE; s->pending_data = calloc(pending_space, sizeof(char)); af->control=control; af->uninit=uninit; af->play=play; af->mul=1; af->data=calloc(1,sizeof(af_data_t)); af->setup=s; init_avcodec(); s->lavc_acodec = avcodec_find_encoder_by_name("ac3"); if (!s->lavc_acodec) { mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_LavcAudioCodecNotFound, "ac3"); return AF_ERROR; } s->lavc_actx = avcodec_alloc_context(); if (!s->lavc_actx) { mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_CouldntAllocateLavcContext); return AF_ERROR; } return AF_OK; }
static int vf_open(vf_instance_t *vf, char *args){ int log2c=-1; vf->config=config; vf->put_image=put_image; vf->get_image=get_image; vf->query_format=query_format; vf->uninit=uninit; vf->control= control; vf->priv=malloc(sizeof(struct vf_priv_s)); memset(vf->priv, 0, sizeof(struct vf_priv_s)); init_avcodec(); vf->priv->log2_count= 4; if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode); if( log2c >=0 && log2c <=8 ) vf->priv->log2_count = log2c; if(vf->priv->qp < 0) vf->priv->qp = 0; // #if HAVE_MMX // if(gCpuCaps.hasMMX){ // store_slice= store_slice_mmx; // } // #endif return 1; }
static int vf_open(vf_instance_t *vf, char *args){ int p_quality=0; float p_fps=0; vf->config=config; vf->put_image=put_image; vf->query_format=query_format; vf->priv=malloc(sizeof(struct vf_priv_s)); memset(vf->priv,0,sizeof(struct vf_priv_s)); init_avcodec(); vf->priv->codec = avcodec_find_encoder_by_name("mpeg1video"); if (!vf->priv->codec) { mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_MissingLAVCcodec, "mpeg1video"); return 0; } vf->priv->context=avcodec_alloc_context3(vf->priv->codec); vf->priv->pic = av_frame_alloc(); // TODO: parse args -> if(args) sscanf(args, "%d:%f", &p_quality, &p_fps); if(p_quality<32){ // fixed qscale lavc_venc_context.flags = CODEC_FLAG_QSCALE; lavc_venc_context.global_quality = vf->priv->pic->quality = (int)(FF_QP2LAMBDA * ((p_quality<1) ? 1 : p_quality) + 0.5); } else { // fixed bitrate (in kbits) lavc_venc_context.bit_rate = 1000*p_quality; } lavc_venc_context.time_base.num = 1000*1001; lavc_venc_context.time_base.den = (p_fps<1.0) ? 1000*1001*25 : (p_fps * lavc_venc_context.time_base.num); lavc_venc_context.gop_size = 0; // I-only lavc_venc_context.pix_fmt= AV_PIX_FMT_YUV420P; return 1; }
/** * Decode a subtitle packet via libavcodec. * \return < 0 on error, > 0 if further processing is needed */ int decode_avsub(struct sh_sub *sh, uint8_t **data, int *size, double *pts, double *endpts) { AVCodecContext *ctx = sh->context; enum CodecID cid = CODEC_ID_NONE; int new_type = 0; int res; int got_sub; AVSubtitle sub; AVPacket pkt; switch (sh->type) { case 'b': cid = CODEC_ID_DVB_SUBTITLE; break; case 'p': cid = CODEC_ID_HDMV_PGS_SUBTITLE; break; case 'x': cid = CODEC_ID_XSUB; break; } av_init_packet(&pkt); pkt.data = *data; pkt.size = *size; pkt.pts = *pts * 1000; if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE) pkt.convergence_duration = (*endpts - *pts) * 1000; if (!ctx) { AVCodec *sub_codec; init_avcodec(); ctx = avcodec_alloc_context3(NULL); sub_codec = avcodec_find_decoder(cid); if (!ctx || !sub_codec || avcodec_open2(ctx, sub_codec, NULL) < 0) { mp_msg(MSGT_SUBREADER, MSGL_FATAL, "Could not open subtitle decoder\n"); av_freep(&ctx); return -1; } sh->context = ctx; } res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt); if (res < 0) return res; if (*pts != MP_NOPTS_VALUE) { if (sub.end_display_time > sub.start_display_time) *endpts = *pts + sub.end_display_time / 1000.0; *pts += sub.start_display_time / 1000.0; } if (got_sub && vo_spudec && sub.num_rects == 0) spudec_set_paletted(vo_spudec, NULL, 0, NULL, 0, 0, 0, 0, *pts, *endpts); if (got_sub && sub.num_rects > 0) { switch (sub.rects[0]->type) { case SUBTITLE_BITMAP: if (!vo_spudec) vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0); spudec_set_paletted(vo_spudec, sub.rects[0]->pict.data[0], sub.rects[0]->pict.linesize[0], sub.rects[0]->pict.data[1], sub.rects[0]->x, sub.rects[0]->y, sub.rects[0]->w, sub.rects[0]->h, *pts, *endpts); vo_osd_changed(OSDTYPE_SPU); break; case SUBTITLE_TEXT: *data = strdup(sub.rects[0]->text); *size = strlen(*data); new_type = 't'; break; case SUBTITLE_ASS: *data = strdup(sub.rects[0]->ass); *size = strlen(*data); new_type = 'a'; break; } } if (got_sub) avsubtitle_free(&sub); return new_type; }
int mpae_init_lavc(audio_encoder_t *encoder) { encoder->params.samples_per_frame = encoder->params.sample_rate; encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; if(!lavc_param_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); return 0; } init_avcodec(); lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); if (!lavc_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); return 0; } if(lavc_param_atag == 0) { lavc_param_atag = av_codec_get_tag(mp_wav_taglists, lavc_acodec->id); if(!lavc_param_atag) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); return 0; } } lavc_actx = avcodec_alloc_context(); if(lavc_actx == NULL) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); return 0; } lavc_actx->codec_type = CODEC_TYPE_AUDIO; lavc_actx->codec_id = lavc_acodec->id; // put sample parameters lavc_actx->channels = encoder->params.channels; lavc_actx->sample_rate = encoder->params.sample_rate; lavc_actx->time_base.num = 1; lavc_actx->time_base.den = encoder->params.sample_rate; if(lavc_param_abitrate<1000) lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000; else lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate; if(lavc_param_audio_avopt){ if(parse_avopts(lavc_actx, lavc_param_audio_avopt) < 0){ mp_msg(MSGT_MENCODER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param_audio_avopt); return 0; } } /* * Special case for adpcm_ima_wav. * The bitrate is only dependent on samplerate. * We have to known frame_size and block_align in advance, * so I just copied the code from libavcodec/adpcm.c * * However, ms adpcm_ima_wav uses a block_align of 2048, * lavc defaults to 1024 */ if(lavc_param_atag == 0x11) { int blkalign = 2048; int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; } if((lavc_param_audio_global_header&1) /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; } if(lavc_param_audio_global_header&2){ lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; } if(avcodec_open(lavc_actx, lavc_acodec) < 0) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); return 0; } if(lavc_param_atag == 0x11) { lavc_actx->block_align = 2048; lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; } encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; while (encoder->decode_buffer_size < 1024) encoder->decode_buffer_size *= 2; encoder->bind = bind_lavc; encoder->get_frame_size = get_frame_size; encoder->encode = encode_lavc; encoder->close = close_lavc; return 1; }
// init driver static int init(sh_video_t *sh){ AVCodecContext *avctx; vd_ffmpeg_ctx *ctx; AVCodec *lavc_codec; int lowres_w=0; int do_vis_debug= lavc_param_vismv || (lavc_param_debug&(FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP)); // slice is rather broken with threads, so disable that combination unless // explicitly requested int use_slices = vd_use_slices > 0 || (vd_use_slices < 0 && lavc_param_threads <= 1); AVDictionary *opts = NULL; init_avcodec(); ctx = sh->context = malloc(sizeof(vd_ffmpeg_ctx)); if (!ctx) return 0; memset(ctx, 0, sizeof(vd_ffmpeg_ctx)); lavc_codec = avcodec_find_decoder_by_name(sh->codec->dll); if(!lavc_codec){ mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MissingLAVCcodec, sh->codec->dll); uninit(sh); return 0; } if (auto_threads) { #if (defined(__MINGW32__) && HAVE_PTHREADS) lavc_param_threads = pthread_num_processors_np(); #elif defined(__linux__) /* Code stolen from x264 :) */ unsigned int bit; int np; cpu_set_t p_aff; memset( &p_aff, 0, sizeof(p_aff) ); sched_getaffinity( 0, sizeof(p_aff), &p_aff ); for( np = 0, bit = 0; bit < sizeof(p_aff); bit++ ) np += (((uint8_t *)&p_aff)[bit / 8] >> (bit % 8)) & 1; lavc_param_threads = np; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__) || defined (__NetBSD__) || defined(__OpenBSD__) /* Code stolen from x264 :) */ int numberOfCPUs; size_t length = sizeof( numberOfCPUs ); #if defined (__NetBSD__) || defined(__OpenBSD__) int mib[2] = { CTL_HW, HW_NCPU }; if( sysctl(mib, 2, &numberOfCPUs, &length, NULL, 0) ) #else if( sysctlbyname("hw.ncpu", &numberOfCPUs, &length, NULL, 0) ) #endif { numberOfCPUs = 1; } lavc_param_threads = numberOfCPUs; #endif if(lavc_codec->id == CODEC_ID_H264 || lavc_codec->id == CODEC_ID_FFH264 || lavc_codec->id == CODEC_ID_MPEG2TS || lavc_codec->id == CODEC_ID_MPEG2VIDEO_XVMC) { if (lavc_param_threads > 16) lavc_param_threads = 16; if (lavc_param_threads > 1 && (lavc_codec->id == CODEC_ID_MPEG2VIDEO || lavc_codec->id == CODEC_ID_MPEG2TS || lavc_codec->id == CODEC_ID_MPEG2VIDEO_XVMC)) vd_use_slices = 0; mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Spawning %d decoding thread%s...\n", lavc_param_threads, lavc_param_threads == 1 ? "" : "s"); } else { lavc_param_threads = 1; } } if(use_slices && (lavc_codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND) && !do_vis_debug) ctx->do_slices=1; if(lavc_codec->capabilities&CODEC_CAP_DR1 && !do_vis_debug && lavc_codec->id != CODEC_ID_INTERPLAY_VIDEO && lavc_codec->id != CODEC_ID_VP8) ctx->do_dr1=1; ctx->nonref_dr = lavc_codec->id == CODEC_ID_H264; ctx->ip_count= ctx->b_count= 0; ctx->pic = avcodec_alloc_frame(); ctx->avctx = avcodec_alloc_context3(lavc_codec); avctx = ctx->avctx; avctx->opaque = sh; avctx->codec_id = lavc_codec->id; avctx->get_format = get_format; if(ctx->do_dr1){ avctx->flags|= CODEC_FLAG_EMU_EDGE; avctx-> get_buffer= get_buffer; avctx->release_buffer= release_buffer; avctx-> reget_buffer= get_buffer; } avctx->flags|= lavc_param_bitexact; avctx->coded_width = sh->disp_w; avctx->coded_height= sh->disp_h; avctx->workaround_bugs= lavc_param_workaround_bugs; switch (lavc_param_error_resilience) { case 5: avctx->err_recognition |= AV_EF_EXPLODE | AV_EF_COMPLIANT | AV_EF_CAREFUL; break; case 4: case 3: avctx->err_recognition |= AV_EF_AGGRESSIVE; // Fallthrough case 2: avctx->err_recognition |= AV_EF_COMPLIANT; // Fallthrough case 1: avctx->err_recognition |= AV_EF_CAREFUL; } lavc_param_gray|= CODEC_FLAG_GRAY; #ifdef CODEC_FLAG2_SHOW_ALL if(!lavc_param_wait_keyframe) avctx->flags2 |= CODEC_FLAG2_SHOW_ALL; #endif avctx->flags2|= lavc_param_fast; avctx->codec_tag= sh->format; avctx->stream_codec_tag= sh->video.fccHandler; avctx->idct_algo= lavc_param_idct_algo; avctx->error_concealment= lavc_param_error_concealment; avctx->debug= lavc_param_debug; if (lavc_param_debug) av_log_set_level(AV_LOG_DEBUG); avctx->debug_mv= lavc_param_vismv; avctx->skip_top = lavc_param_skip_top; avctx->skip_bottom= lavc_param_skip_bottom; if(lavc_param_lowres_str != NULL) { sscanf(lavc_param_lowres_str, "%d,%d", &lavc_param_lowres, &lowres_w); if(lavc_param_lowres < 1 || lavc_param_lowres > 16 || (lowres_w > 0 && avctx->width < lowres_w)) lavc_param_lowres = 0; avctx->lowres = lavc_param_lowres; } avctx->skip_loop_filter = str2AVDiscard(lavc_param_skip_loop_filter_str); avctx->skip_idct = str2AVDiscard(lavc_param_skip_idct_str); avctx->skip_frame = str2AVDiscard(lavc_param_skip_frame_str); if(lavc_avopt){ if (parse_avopts(avctx, lavc_avopt) < 0 && (!lavc_codec->priv_class || parse_avopts(avctx->priv_data, lavc_avopt) < 0)) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_avopt); uninit(sh); return 0; } } skip_idct = avctx->skip_idct; skip_frame = avctx->skip_frame; mp_dbg(MSGT_DECVIDEO, MSGL_DBG2, "libavcodec.size: %d x %d\n", avctx->width, avctx->height); switch (sh->format) { case mmioFOURCC('S','V','Q','3'): /* SVQ3 extradata can show up as sh->ImageDesc if demux_mov is used, or in the phony AVI header if demux_lavf is used. The first case is handled here; the second case falls through to the next section. */ if (sh->ImageDesc) { avctx->extradata_size = (*(int *)sh->ImageDesc) - sizeof(int); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, ((int *)sh->ImageDesc)+1, avctx->extradata_size); break; } /* fallthrough */ case mmioFOURCC('A','V','R','n'): case mmioFOURCC('M','J','P','G'): /* AVRn stores huffman table in AVI header */ /* Pegasus MJPEG stores it also in AVI header, but it uses the common MJPG fourcc :( */ if (!sh->bih || sh->bih->biSize <= sizeof(*sh->bih)) break; av_dict_set(&opts, "extern_huff", "1", 0); avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); #if 0 { int x; uint8_t *p = avctx->extradata; for (x=0; x<avctx->extradata_size; x++) mp_msg(MSGT_DECVIDEO, MSGL_INFO, "[%x] ", p[x]); mp_msg(MSGT_DECVIDEO, MSGL_INFO, "\n"); } #endif break; case mmioFOURCC('R', 'V', '1', '0'): case mmioFOURCC('R', 'V', '1', '3'): case mmioFOURCC('R', 'V', '2', '0'): case mmioFOURCC('R', 'V', '3', '0'): case mmioFOURCC('R', 'V', '4', '0'): if(sh->bih->biSize<sizeof(*sh->bih)+8){ /* only 1 packet per frame & sub_id from fourcc */ avctx->extradata_size= 8; avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); ((uint32_t *)avctx->extradata)[0] = 0; ((uint32_t *)avctx->extradata)[1] = (sh->format == mmioFOURCC('R', 'V', '1', '3')) ? 0x10003001 : 0x10000000; } else { /* has extra slice header (demux_rm or rm->avi streamcopy) */ avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); } avctx->sub_id= AV_RB32(avctx->extradata+4); // printf("%X %X %d %d\n", extrahdr[0], extrahdr[1]); break; default: if (!sh->bih || sh->bih->biSize <= sizeof(*sh->bih)) break; avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); break; } if(sh->bih) avctx->bits_per_coded_sample= sh->bih->biBitCount; avctx->thread_count = lavc_param_threads; avctx->thread_type = FF_THREAD_FRAME | FF_THREAD_SLICE; if(lavc_codec->capabilities & CODEC_CAP_HWACCEL) // HACK around badly placed checks in mpeg_mc_decode_init set_format_params(avctx, PIX_FMT_XVMC_MPEG2_IDCT); /* open it */ if (avcodec_open2(avctx, lavc_codec, &opts) < 0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantOpenCodec); uninit(sh); return 0; } av_dict_free(&opts); // this is necessary in case get_format was never called and init_vo is // too late e.g. for H.264 VDPAU set_format_params(avctx, avctx->pix_fmt); mp_msg(MSGT_DECVIDEO, MSGL_V, "INFO: libavcodec init OK!\n"); return 1; //mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, IMGFMT_YV12); }
static int init(sh_audio_t *sh_audio) { int tries = 0; int x; AVCodecContext *lavc_context; AVCodec *lavc_codec; AVDictionary *opts = NULL; char tmpstr[50]; mp_msg(MSGT_DECAUDIO,MSGL_V,"FFmpeg's libavcodec audio codec\n"); init_avcodec(); lavc_codec = 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_context3(lavc_codec); sh_audio->context=lavc_context; snprintf(tmpstr, sizeof(tmpstr), "%f", drc_level); av_dict_set(&opts, "drc_scale", tmpstr, 0); lavc_context->sample_rate = sh_audio->samplerate; lavc_context->bit_rate = sh_audio->i_bps * 8; 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_coded_sample = sh_audio->wf->wBitsPerSample; } lavc_context->request_channels = audio_output_channels; 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, sh_audio->wf + 1, 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_open2(lavc_context, lavc_codec, &opts) < 0) { mp_msg(MSGT_DECAUDIO,MSGL_ERR, MSGTR_CantOpenCodec); return 0; } av_dict_free(&opts); mp_msg(MSGT_DECAUDIO,MSGL_V,"INFO: libavcodec \"%s\" init OK!\n", lavc_codec->name); // 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) do { x=decode_audio(sh_audio,sh_audio->a_buffer,1,sh_audio->a_buffer_size); } while (x <= 0 && tries++ < 5); if(x>0) sh_audio->a_buffer_len=x; sh_audio->i_bps=lavc_context->bit_rate/8; if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec) sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; switch (lavc_context->sample_fmt) { case AV_SAMPLE_FMT_U8: case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_FLT: break; default: return 0; } return 1; }
// init driver static int init(sh_video_t *sh){ AVCodecContext *avctx; vd_ffmpeg_ctx *ctx; AVCodec *lavc_codec; int lowres_w=0; AVDictionary *opts = NULL; init_avcodec(); ctx = sh->context = malloc(sizeof(vd_ffmpeg_ctx)); if (!ctx) return 0; memset(ctx, 0, sizeof(vd_ffmpeg_ctx)); lavc_codec = avcodec_find_decoder_by_name(sh->codec->dll); if(!lavc_codec){ mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MissingLAVCcodec, sh->codec->dll); uninit(sh); return 0; } ctx->ip_count= ctx->b_count= 0; ctx->pic = avcodec_alloc_frame(); ctx->avctx = avcodec_alloc_context3(lavc_codec); avctx = ctx->avctx; avctx->opaque = sh; avctx->codec_id = lavc_codec->id; avctx->get_format = get_format; avctx->flags|= lavc_param_bitexact; avctx->coded_width = sh->disp_w; avctx->coded_height= sh->disp_h; avctx->workaround_bugs= lavc_param_workaround_bugs; switch (lavc_param_error_resilience) { case 5: avctx->err_recognition |= AV_EF_EXPLODE | AV_EF_COMPLIANT | AV_EF_CAREFUL; break; case 4: case 3: avctx->err_recognition |= AV_EF_AGGRESSIVE; // Fallthrough case 2: avctx->err_recognition |= AV_EF_COMPLIANT; // Fallthrough case 1: avctx->err_recognition |= AV_EF_CAREFUL; } lavc_param_gray|= CODEC_FLAG_GRAY; #ifdef CODEC_FLAG2_SHOW_ALL if(!lavc_param_wait_keyframe) avctx->flags2 |= CODEC_FLAG2_SHOW_ALL; #endif avctx->flags2|= lavc_param_fast; avctx->codec_tag= sh->format; avctx->stream_codec_tag= sh->video.fccHandler; avctx->idct_algo= lavc_param_idct_algo; avctx->error_concealment= lavc_param_error_concealment; avctx->debug= lavc_param_debug; if (lavc_param_debug) av_log_set_level(AV_LOG_DEBUG); avctx->debug_mv= lavc_param_vismv; avctx->skip_top = lavc_param_skip_top; avctx->skip_bottom= lavc_param_skip_bottom; if(lavc_param_lowres_str != NULL) { sscanf(lavc_param_lowres_str, "%d,%d", &lavc_param_lowres, &lowres_w); if(lavc_param_lowres < 1 || lavc_param_lowres > 16 || (lowres_w > 0 && avctx->width < lowres_w)) lavc_param_lowres = 0; avctx->lowres = lavc_param_lowres; } avctx->skip_loop_filter = str2AVDiscard(lavc_param_skip_loop_filter_str); avctx->skip_idct = str2AVDiscard(lavc_param_skip_idct_str); avctx->skip_frame = str2AVDiscard(lavc_param_skip_frame_str); av_opt_set_int(avctx, "skip_alpha", 1, 0); if(lavc_avopt){ if (parse_avopts(avctx, lavc_avopt) < 0 && (!lavc_codec->priv_class || parse_avopts(avctx->priv_data, lavc_avopt) < 0)) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_avopt); uninit(sh); return 0; } } skip_idct = avctx->skip_idct; skip_frame = avctx->skip_frame; mp_dbg(MSGT_DECVIDEO, MSGL_DBG2, "libavcodec.size: %d x %d\n", avctx->width, avctx->height); switch (sh->format) { case mmioFOURCC('S','V','Q','3'): /* SVQ3 extradata can show up as sh->ImageDesc if demux_mov is used, or in the phony AVI header if demux_lavf is used. The first case is handled here; the second case falls through to the next section. */ if (sh->ImageDesc) { avctx->extradata_size = (*(int *)sh->ImageDesc) - sizeof(int); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, ((int *)sh->ImageDesc)+1, avctx->extradata_size); break; } /* fallthrough */ case mmioFOURCC('A','V','R','n'): case mmioFOURCC('M','J','P','G'): /* AVRn stores huffman table in AVI header */ /* Pegasus MJPEG stores it also in AVI header, but it uses the common MJPG fourcc :( */ if (!sh->bih || sh->bih->biSize <= sizeof(*sh->bih)) break; av_dict_set(&opts, "extern_huff", "1", 0); avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); #if 0 { int x; uint8_t *p = avctx->extradata; for (x=0; x<avctx->extradata_size; x++) mp_msg(MSGT_DECVIDEO, MSGL_INFO, "[%x] ", p[x]); mp_msg(MSGT_DECVIDEO, MSGL_INFO, "\n"); } #endif break; case mmioFOURCC('R', 'V', '1', '0'): case mmioFOURCC('R', 'V', '1', '3'): case mmioFOURCC('R', 'V', '2', '0'): case mmioFOURCC('R', 'V', '3', '0'): case mmioFOURCC('R', 'V', '4', '0'): if(sh->bih->biSize<sizeof(*sh->bih)+8){ /* only 1 packet per frame & sub_id from fourcc */ avctx->extradata_size= 8; avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); ((uint32_t *)avctx->extradata)[0] = 0; ((uint32_t *)avctx->extradata)[1] = (sh->format == mmioFOURCC('R', 'V', '1', '3')) ? 0x10003001 : 0x10000000; } else { /* has extra slice header (demux_rm or rm->avi streamcopy) */ avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); } // printf("%X %X %d %d\n", extrahdr[0], extrahdr[1]); break; default: if (!sh->bih || sh->bih->biSize <= sizeof(*sh->bih)) break; avctx->extradata_size = sh->bih->biSize-sizeof(*sh->bih); avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size); break; } if(sh->bih) avctx->bits_per_coded_sample= sh->bih->biBitCount; set_dr_slice_settings(avctx, lavc_codec); if(lavc_codec->capabilities & CODEC_CAP_HWACCEL) // HACK around badly placed checks in mpeg_mc_decode_init set_format_params(avctx, PIX_FMT_XVMC_MPEG2_IDCT); avctx->thread_count = lavc_param_threads; avctx->thread_type = FF_THREAD_FRAME | FF_THREAD_SLICE; /* open it */ if (avcodec_open2(avctx, lavc_codec, &opts) < 0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantOpenCodec); uninit(sh); return 0; } av_dict_free(&opts); // this is necessary in case get_format was never called and init_vo is // too late e.g. for H.264 VDPAU set_format_params(avctx, avctx->pix_fmt); mp_msg(MSGT_DECVIDEO, MSGL_V, "INFO: libavcodec init OK!\n"); return 1; //mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, IMGFMT_YV12); }
/** * \param vf pointer to the vf instance structure * \param args the argument list string for the -vf zrmjpeg command * * \returns 0 for error, 1 for success * * This routine will do some basic initialization of local structures etc., * and then parse the command line arguments specific for the ZRMJPEG filter. */ static int vf_open(vf_instance_t *vf, char *args){ struct vf_priv_s *priv; VERBOSE("vf_open() called: args=\"%s\"\n", args); vf->config = config; vf->put_image = put_image; vf->query_format = query_format; vf->uninit = uninit; priv = vf->priv = calloc(sizeof(*priv), 1); if (!vf->priv) { ERROR("out of memory error\n"); return 0; } /* maximum displayable size by zoran card, these defaults * are for my own zoran card in PAL mode, these can be changed * by filter options. But... in an ideal world these values would * be queried from the vo device itself... */ priv->maxwidth = 768; priv->maxheight = 576; priv->quality = 2; priv->hdec = 1; priv->vdec = 1; init_avcodec(); if (args) { char *arg, *tmp, *ptr, junk; int last = 0, input; /* save arguments, to be able to safely modify them */ arg = strdup(args); if (!arg) { ERROR("out of memory, this is bad\n"); return 0; } tmp = ptr = arg; do { while (*tmp != ':' && *tmp) tmp++; if (*tmp == ':') *tmp++ = '\0'; else last = 1; VERBOSE("processing filter option \"%s\"\n", ptr); /* These options deal with the maximum output * resolution of the zoran card. These should * be queried from the vo device, but it is currently * too difficult, so the user should tell the filter */ if (!strncmp("maxheight=", ptr, 10)) { if (sscanf(ptr+10, "%d%c", &input, &junk) != 1) ERROR( "error parsing parameter to \"maxheight=\", \"%s\", ignoring\n" , ptr + 10); else { priv->maxheight = input; VERBOSE("setting maxheight to %d\n", priv->maxheight); } } else if (!strncmp("quality=", ptr, 8)) { if (sscanf(ptr+8, "%d%c", &input, &junk) != 1) ERROR( "error parsing parameter to \"quality=\", \"%s\", ignoring\n" , ptr + 8); else if (input < 1 || input > 20) ERROR( "parameter to \"quality=\" out of range (1..20), %d\n", input); else { priv->quality = input; VERBOSE("setting JPEG quality to %d\n", priv->quality); } } else if (!strncmp("maxwidth=", ptr, 9)) { if (sscanf(ptr+9, "%d%c", &input, &junk) != 1) ERROR( "error parsing parameter to \"maxwidth=\", \"%s\", ignoring\n" , ptr + 9); else { priv->maxwidth = input; VERBOSE("setting maxwidth to %d\n", priv->maxwidth); } } else if (!strncmp("hdec=", ptr, 5)) { if (sscanf(ptr+5, "%d%c", &input, &junk) != 1) ERROR( "error parsing parameter to \"hdec=\", \"%s\", ignoring\n" , ptr + 9); else if (input != 1 && input != 2 && input != 4) ERROR( "illegal parameter to \"hdec=\", %d, should be 1, 2 or 4", input); else { priv->hdec = input; VERBOSE( "setting horizontal decimation to %d\n", priv->maxwidth); } } else if (!strncmp("vdec=", ptr, 5)) { if (sscanf(ptr+5, "%d%c", &input, &junk) != 1) ERROR( "error parsing parameter to \"vdec=\", \"%s\", ignoring\n" , ptr + 9); else if (input != 1 && input != 2 && input != 4) ERROR( "illegal parameter to \"vdec=\", %d, should be 1, 2 or 4", input); else { priv->vdec = input; VERBOSE( "setting vertical decimation to %d\n", priv->maxwidth); } } else if (!strcasecmp("dc10+-PAL", ptr) || !strcasecmp("dc10-PAL", ptr)) { priv->maxwidth = 768; priv->maxheight = 576; VERBOSE("setting DC10(+) PAL profile\n"); } else if (!strcasecmp("fd", ptr)) { priv->fd = 1; VERBOSE("forcing decimation\n"); } else if (!strcasecmp("nofd", ptr)) { priv->fd = 0; VERBOSE("decimate only if beautiful\n"); } else if (!strcasecmp("bw", ptr)) { priv->bw = 1; VERBOSE("setting black and white encoding\n"); } else if (!strcasecmp("color", ptr)) { priv->bw = 0; VERBOSE("setting color encoding\n"); } else if (!strcasecmp("dc10+-NTSC", ptr) || !strcasecmp("dc10-NTSC", ptr)) { priv->maxwidth = 640; priv->maxheight = 480; VERBOSE("setting DC10(+) NTSC profile\n"); } else if (!strcasecmp("buz-PAL", ptr) || !strcasecmp("lml33-PAL", ptr)) { priv->maxwidth = 720; priv->maxheight = 576; VERBOSE("setting buz/lml33 PAL profile\n"); } else if (!strcasecmp("buz-NTSC", ptr) || !strcasecmp("lml33-NTSC", ptr)) { priv->maxwidth = 720; priv->maxheight = 480; VERBOSE("setting buz/lml33 NTSC profile\n"); } else { WARNING("ignoring unknown filter option " "\"%s\", or missing argument\n", ptr); } ptr = tmp; } while (!last); free(arg); } return 1; }
/** * \brief initialize mjpeg encoder * * This routine is to set up the parameters and initialize the mjpeg encoder. * It does all the initializations needed of lower level routines. * The formats accepted by this encoder is YUV422P and YUV420 * * \param w width in pixels of the image to encode, must be a multiple of 16 * \param h height in pixels of the image to encode, must be a multiple of 8 * \param y_rsize size of each plane row Y component * \param y_rsize size of each plane row U component * \param v_rsize size of each plane row V component * \param cu "cheap upsample". Set to 0 for YUV422 format, 1 for YUV420 format * when set to 1, the encoder will assume that there is only half th * number of rows of chroma information, and every chroma row is * duplicated. * \param q quality parameter for the mjpeg encode. Between 1 and 20 where 1 * is best quality and 20 is the worst quality. * \param b monochrome flag. When set to 1, the mjpeg output is monochrome. * In that case, the colour information is omitted, and actually the * colour planes are not touched. * * \returns an appropriately set up jpeg_enc_t structure * * The actual plane buffer addreses are passed by jpeg_enc_frame(). * * The encoder doesn't know anything about interlacing, the halve height * needs to be passed and the double rowstride. Which field gets encoded * is decided by what buffers are passed to mjpeg_encode_frame() */ static jpeg_enc_t *jpeg_enc_init(int w, int h, int y_rsize, int u_rsize, int v_rsize, int cu, int q, int b) { jpeg_enc_t *j; int i = 0; VERBOSE("JPEG encoder init: %dx%d %d %d %d cu=%d q=%d bw=%d\n", w, h, y_rsize, u_rsize, v_rsize, cu, q, b); j = av_mallocz(sizeof(jpeg_enc_t)); if (j == NULL) return NULL; j->s = av_mallocz(sizeof(MpegEncContext)); if (j->s == NULL) { av_free(j); return NULL; } /* info on how to access the pixels */ j->y_rs = y_rsize; j->u_rs = u_rsize; j->v_rs = v_rsize; j->s->width = w; // image width and height j->s->height = h; j->s->qscale = q; // Encoding quality j->s->out_format = FMT_MJPEG; j->s->intra_only = 1; // Generate only intra pictures for jpeg j->s->encoding = 1; // Set mode to encode j->s->pict_type = AV_PICTURE_TYPE_I; j->s->y_dc_scale = 8; j->s->c_dc_scale = 8; /* * This sets up the MCU (Minimal Code Unit) number * of appearances of the various component * for the SOF0 table in the generated MJPEG. * The values are not used for anything else. * The current setup is simply YUV422, with two horizontal Y components * for every UV component. */ //FIXME j->s->mjpeg_write_tables = 1; // setup to write tables j->s->mjpeg_vsample[0] = 1; // 1 appearance of Y vertically j->s->mjpeg_vsample[1] = 1; // 1 appearance of U vertically j->s->mjpeg_vsample[2] = 1; // 1 appearance of V vertically j->s->mjpeg_hsample[0] = 2; // 2 appearances of Y horizontally j->s->mjpeg_hsample[1] = 1; // 1 appearance of U horizontally j->s->mjpeg_hsample[2] = 1; // 1 appearance of V horizontally j->cheap_upsample = cu; j->bw = b; init_avcodec(); // Build mjpeg huffman code tables, setting up j->s->mjpeg_ctx if (ff_mjpeg_encode_init(j->s) < 0) { av_free(j->s); av_free(j); return NULL; } /* alloc bogus avctx to keep MPV_common_init from segfaulting */ j->s->avctx = avcodec_alloc_context(); if (j->s->avctx == NULL) { av_free(j->s); av_free(j); return NULL; } // Set some a minimum amount of default values that are needed // Indicates that we should generated normal MJPEG j->s->avctx->codec_id = AV_CODEC_ID_MJPEG; // Which DCT method to use. AUTO will select the fastest one j->s->avctx->dct_algo = FF_DCT_AUTO; j->s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x // indicate we 'decode' to jpeg 4:2:2 j->s->avctx->pix_fmt = PIX_FMT_YUVJ422P; j->s->avctx->thread_count = 1; /* make MPV_common_init allocate important buffers, like s->block * Also initializes dsputil */ if (ff_MPV_common_init(j->s) < 0) { av_free(j->s); av_free(j); return NULL; } /* correct the value for sc->mb_height. MPV_common_init put other * values there */ j->s->mb_height = j->s->height/8; j->s->mb_intra = 1; // Init q matrix j->s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; for (i = 1; i < 64; i++) j->s->intra_matrix[i] = av_clip_uint8( (ff_mpeg1_default_intra_matrix[i]*j->s->qscale) >> 3); // precompute matrix convert_matrix(j->s, j->s->q_intra_matrix, j->s->q_intra_matrix16, j->s->intra_matrix, j->s->intra_quant_bias, 8, 8); /* Pick up the selection of the optimal get_pixels() routine * to use, which was done in MPV_common_init() */ get_pixels = j->s->dsp.get_pixels; return j; }