uint32_t vidix_query_fourcc(uint32_t format) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vosub_vidix: query_format was called: %x (%s)\n",format,vo_format_name(format)); } vidix_fourcc.fourcc = format; vdlQueryFourcc(vidix_handler,&vidix_fourcc); if (vidix_fourcc.depth == VID_DEPTH_NONE) return 0; return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_HWSCALE_UP|VFCAP_HWSCALE_DOWN|VFCAP_OSD|VFCAP_ACCEPT_STRIDE; }
void vidix_flip_page(void) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vosub_vidix: vidix_flip_page() was called\n"); } if(vo_doublebuffering) { vdlPlaybackFrameSelect(vidix_handler,next_frame); next_frame=(next_frame+1)%vidix_play.num_frames; } }
static int init_vqf_audio_codec(sh_audio_t *sh_audio){ WAVEFORMATEX *in_fmt=sh_audio->wf; vqf_priv_t*priv=sh_audio->context; int ver; mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n"); sh_audio->channels=in_fmt->nChannels; sh_audio->samplerate=in_fmt->nSamplesPerSec; sh_audio->sample_format=AF_FORMAT_S16_NE; // sh_audio->sample_format=AF_FORMAT_FLOAT_NE; sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8; priv->o_wf.nChannels=in_fmt->nChannels; priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec; priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels; priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels; priv->o_wf.wFormatTag=0x01; priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample; priv->o_wf.cbSize=0; if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) { mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n"); print_wave_header(in_fmt, MSGL_V); mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n"); print_wave_header(&priv->o_wf, MSGL_V); } memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo)); if((ver=TvqInitialize(&priv->hi,&priv->index,0))){ const char *tvqe[]={ "No errors", "General error", "Wrong version", "Channel setting error", "Wrong coding mode", "Inner parameter setting error", "Wrong number of VQ pre-selection candidates, used only in encoder" }; mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown"); return 0; } ver=TvqCheckVersion(priv->hi.ID); if(ver==TVQ_UNKNOWN_VERSION){ mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" ); return 0; } TvqGetConfInfo(&priv->cf); TvqGetVectorInfo(priv->bits_0,priv->bits_1); priv->framesize=TvqGetFrameSize(); sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels; sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize; sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size); sh_audio->a_in_buffer_len=0; return 1; }
static uint32_t vidix_draw_image(mp_image_t *mpi){ if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vosub_vidix: vidix_draw_image() was called\n"); } // if -dr or -slices then do nothing: if(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK)) return VO_TRUE; vo_server->draw_slice(mpi->planes,mpi->stride, vidix_play.src.w,vidix_play.src.h,vidix_play.src.x,vidix_play.src.y); return VO_TRUE; }
static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { struct stream_priv_s* p = (struct stream_priv_s*)opts; char *filename; dvdnav_priv_t *priv; if(p->device) filename = p->device; else if(dvd_device) filename= dvd_device; else filename = DEFAULT_DVD_DEVICE; if(!(priv=new_dvdnav_stream(filename))) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_CantOpenDVD,filename, strerror(errno)); return STREAM_UNSUPPORTED; } if(p->track > 0) { if(dvd_chapter > 0 && dvd_last_chapter > 0 && dvd_chapter > dvd_last_chapter) { mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, invalid chapter range: %d > %d\n", dvd_chapter, dvd_last_chapter); return STREAM_UNSUPPORTED; } priv->title = p->track; if(dvdnav_title_play(priv->dvdnav, p->track) != DVDNAV_STATUS_OK) { mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, couldn't select title %d, error '%s'\n", p->track, dvdnav_err_to_string(priv->dvdnav)); return STREAM_UNSUPPORTED; } if(dvd_chapter > 0) dvdnav_part_play(priv->dvdnav, p->track, dvd_chapter); } else if(p->track == -1) dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root); else { mp_msg(MSGT_OPEN,MSGL_INFO,"dvdnav_stream, you didn't specify a track number (as in dvdnav://1), playing whole disc\n"); dvdnav_menu_call(priv->dvdnav, DVD_MENU_Title); } if(mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) identify(priv, p); if(dvd_angle > 1) dvdnav_angle_change(priv->dvdnav, dvd_angle); stream->sector_size = 2048; stream->flags = STREAM_READ | STREAM_SEEK; stream->fill_buffer = fill_buffer; stream->seek = seek; stream->control = control; stream->close = stream_dvdnav_close; stream->type = STREAMTYPE_DVDNAV; stream->priv=(void*)priv; *file_format = DEMUXER_TYPE_MPEG_PS; update_title_len(stream); if(!stream->pos) mp_msg(MSGT_OPEN,MSGL_ERR, "INIT ERROR: couldn't get init pos %s\r\n", dvdnav_err_to_string(priv->dvdnav)); mp_msg(MSGT_OPEN,MSGL_INFO, "Remember to disable MPlayer's cache when playing dvdnav:// streams (adding -nocache to your command line)\r\n"); return STREAM_OK; }
void mp_msg(int mod, int lev, const char *format, ... ){ va_list va; char tmp[MSGSIZE_MAX]; if (! mp_msg_test(mod, lev)) return; va_start(va, format); vsnprintf(tmp, MSGSIZE_MAX, format, va); va_end(va); tmp[MSGSIZE_MAX-2] = '\n'; tmp[MSGSIZE_MAX-1] = 0; printf(tmp); }
void vlvo_flip_page(void) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_osd() was called\n"); } if(vo_doublebuffering) { ioctl(lvo_handler,MGA_VID_FSEL,&next_frame); next_frame=(next_frame+1)%mga_vid_config.num_frames; lvo_mem=frames[next_frame]; } }
void vlvo_draw_osd(void) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2,"vesa_lvo: vlvo_draw_osd() was called\n"); } /* TODO: hw support */ #if 0 /* disable this stuff until new fbvid.h interface will be implemented because in different fourcc radeon_vid and rage128_vid have different width alignment */ vo_draw_text(mga_vid_config.src_width,mga_vid_config.src_height,draw_alpha); #endif }
int stream_seek_long(stream_t *s,off_t pos){ int res; off_t newpos=0; // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos); s->buf_pos=s->buf_len=0; if(s->mode == STREAM_WRITE) { if(!s->seek || !s->seek(s,pos)) return 0; return 1; } if(s->sector_size) newpos = (pos/s->sector_size)*s->sector_size; else newpos = pos&(~((off_t)STREAM_BUFFER_SIZE-1)); if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){ mp_msg(MSGT_STREAM,MSGL_DBG3, "s->pos=%"PRIX64" newpos=%"PRIX64" new_bufpos=%"PRIX64" buflen=%X \n", (int64_t)s->pos,(int64_t)newpos,(int64_t)pos,s->buf_len); } pos-=newpos; res = stream_seek_internal(s, newpos); if (res >= 0) return res; while(s->pos<newpos){ if(stream_fill_buffer(s)<=0) break; // EOF } s->eof = 0; // EOF reset when seek succeeds. while (stream_fill_buffer(s) > 0) { if(pos<=s->buf_len){ s->buf_pos=pos; // byte position in sector return 1; } pos -= s->buf_len; } // Fill failed, but seek still is a success. s->pos += pos; s->buf_pos = 0; s->buf_len = 0; mp_msg(MSGT_STREAM,MSGL_V, "stream_seek: Seek to/past EOF: no buffer preloaded.\n"); return 1; }
// NOTE TO MYSELF: This function is nonsense. // MPlayer should pass messages to the GUI // which must decide then which message has // to be shown (MSGL_FATAL, for example). // But with this function it is at least // possible to show GUI's very critical or // abort messages. void gmp_msg(int mod, int lev, const char *format, ...) { char msg[512]; va_list va; va_start(va, format); vsnprintf(msg, sizeof(msg), format, va); va_end(va); mp_msg(mod, lev, "%s", msg); if (mp_msg_test(mod, lev)) gtkMessageBox(MSGBOX_FATAL, msg); }
static void mp_msp_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) { static int print_prefix=1; AVClass *avc= ptr ? *(AVClass **)ptr : NULL; int type= MSGT_FIXME; int mp_level; switch(level){ case AV_LOG_VERBOSE: mp_level = MSGL_V ; break; case AV_LOG_DEBUG: mp_level= MSGL_V ; break; case AV_LOG_INFO : mp_level= MSGL_INFO; break; case AV_LOG_ERROR: mp_level= MSGL_ERR ; break; default : mp_level= level > AV_LOG_DEBUG ? MSGL_DBG2 : MSGL_ERR; break; } if (ptr && !avc) mp_msg(MSGT_DECVIDEO, MSGL_ERR, "libav* called av_log with context containing a broken AVClass!\n"); if (avc) { if(!strcmp(avc->class_name, "AVCodecContext")){ AVCodecContext *s= ptr; if(s->codec){ if(s->codec->type == AVMEDIA_TYPE_AUDIO){ if(s->codec->decode) type= MSGT_DECAUDIO; }else if(s->codec->type == AVMEDIA_TYPE_VIDEO){ if(s->codec->decode) type= MSGT_DECVIDEO; } //FIXME subtitles, encoders (what msgt for them? there is no appropriate ...) } }else if(!strcmp(avc->class_name, "AVFormatContext")){ AVFormatContext *s= ptr; if(s->iformat) type= MSGT_DEMUXER; else if(s->oformat) type= MSGT_MUXER; } } if (!mp_msg_test(type, mp_level)) return; if(print_prefix && avc) { mp_msg(type, mp_level, "[%s @ %p]", avc->item_name(ptr), avc); } print_prefix= strchr(fmt, '\n') != NULL; mp_msg_va(type, mp_level, fmt, vl); }
void vf_print_filter_chain(int msglevel, struct vf_instance *vf) { if (!mp_msg_test(MSGT_VFILTER, msglevel)) return; for (vf_instance_t *f = vf; f; f = f->next) { mp_msg(MSGT_VFILTER, msglevel, " [%s] ", f->info->name); print_fmt(msglevel, &f->fmt_in); if (f->next) { mp_msg(MSGT_VFILTER, msglevel, " -> "); print_fmt(msglevel, &f->fmt_out); } mp_msg(MSGT_VFILTER, msglevel, "\n"); } }
int stream_seek_long(stream_t *s, int64_t pos){ int res; int64_t newpos=0; // if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos); s->buf_pos=s->buf_len=0; if(s->mode == STREAM_WRITE) { if(!s->seek || !s->seek(s,pos)) return 0; return 1; } if(s->sector_size) newpos = (pos/s->sector_size)*s->sector_size; else newpos = pos&(~((int64_t)STREAM_BUFFER_SIZE-1)); if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){ mp_msg(MSGT_STREAM,MSGL_DBG3, "s->pos=%"PRIX64" newpos=%"PRIX64" new_bufpos=%"PRIX64" buflen=%X \n", (int64_t)s->pos,(int64_t)newpos,(int64_t)pos,s->buf_len); } pos-=newpos; res = stream_seek_internal(s, newpos); if (res >= 0) return res; while(s->pos<newpos){ if(stream_fill_buffer(s)<=0) break; // EOF } while(stream_fill_buffer(s) > 0 && pos >= 0) { if(pos<=s->buf_len){ s->buf_pos=pos; // byte position in sector return 1; } pos -= s->buf_len; } // if(pos==s->buf_len) printf("XXX Seek to last byte of file -> EOF\n"); mp_msg(MSGT_STREAM,MSGL_V,"stream_seek: WARNING! Can't seek to 0x%"PRIX64" !\n",(int64_t)(pos+newpos)); return 0; }
static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) { static bool print_prefix = 1; AVClass *avc = ptr ? *(AVClass **)ptr : NULL; int mp_level = av_log_level_to_mp_level(level); int type = extract_msg_type_from_ctx(ptr); if (!mp_msg_test(type, mp_level)) return; if (print_prefix && avc) mp_msg(type, mp_level, "[%s @ %p]", avc->item_name(ptr), avc); print_prefix = fmt[strlen(fmt) - 1] == '\n'; mp_msg_va(type, mp_level, fmt, vl); }
int http_seek( stream_t *stream, off_t pos ) { HTTP_header_t *http_hdr = NULL; int fd; if( stream==NULL ) return 0; if( stream->fd>0 ) closesocket(stream->fd); // need to reconnect to seek in http-stream fd = http_send_request( stream->streaming_ctrl->url, pos ); if( fd<0 ) return 0; http_hdr = http_read_response( fd ); if( http_hdr==NULL ) return 0; if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) http_debug_hdr( http_hdr ); switch( http_hdr->status_code ) { case 200: case 206: // OK mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") ); mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); if( http_hdr->body_size>0 ) { if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { http_free( http_hdr ); return -1; } } break; default: mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ErrServerReturned, http_hdr->status_code, http_hdr->reason_phrase ); closesocket( fd ); fd = -1; } stream->fd = fd; if( http_hdr ) { http_free( http_hdr ); stream->streaming_ctrl->data = NULL; } stream->pos=pos; return 1; }
uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_slice() was called\n"); } if(src_format == IMGFMT_YV12 || src_format == IMGFMT_I420 || src_format == IMGFMT_IYUV) vlvo_draw_slice_420(image,stride,w,h,x,y); else { uint8_t *dst; uint8_t bytpp; bytpp = (image_bpp+7)/8; dst = lvo_mem + (image_width * y + x)*bytpp; /* vlvo_draw_slice_422(image,stride,w,h,x,y); just for speed */ memcpy(dst,image[0],mga_vid_config.frame_size); } return 0; }
int vlvo_preinit(const char *drvname) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported); return -1; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_preinit(%s) was called\n",drvname); } lvo_handler = open(drvname,O_RDWR); if(lvo_handler == -1) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CouldntOpen,drvname); return -1; } /* we are able to tune up this stuff depend on fourcc format */ video_out_vesa.draw_slice=vlvo_draw_slice; video_out_vesa.draw_frame=vlvo_draw_frame; video_out_vesa.flip_page=vlvo_flip_page; video_out_vesa.draw_osd=vlvo_draw_osd; video_out_vesa.control=vlvo_control; return 0; }
void vo_draw_alpha_init(void){ #ifdef FAST_OSD_TABLE int i; for(i=0;i<256;i++){ fast_osd_15bpp_table[i]=((i>>3)<<10)|((i>>3)<<5)|(i>>3); fast_osd_16bpp_table[i]=((i>>3)<<11)|((i>>2)<<5)|(i>>3); } #endif //FIXME the optimized stuff is a lie for 15/16bpp as they aren't optimized yet if( mp_msg_test(MSGT_OSD,MSGL_V) ) { #if CONFIG_RUNTIME_CPUDETECT #if ARCH_X86 // ordered per speed fasterst first if(gCpuCaps.hasMMX2) mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay\n"); else if(gCpuCaps.has3DNow) mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit 3DNow) Optimized OnScreenDisplay\n"); else if(gCpuCaps.hasMMX) mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX Optimized OnScreenDisplay\n"); else mp_msg(MSGT_OSD,MSGL_INFO,"Using X86 Optimized OnScreenDisplay\n"); #else mp_msg(MSGT_OSD,MSGL_INFO,"Using Unoptimized OnScreenDisplay\n"); #endif #else //CONFIG_RUNTIME_CPUDETECT #if HAVE_MMX2 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay\n"); #elif HAVE_AMD3DNOW mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit 3DNow) Optimized OnScreenDisplay\n"); #elif HAVE_MMX mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX Optimized OnScreenDisplay\n"); #elif ARCH_X86 mp_msg(MSGT_OSD,MSGL_INFO,"Using X86 Optimized OnScreenDisplay\n"); #else mp_msg(MSGT_OSD,MSGL_INFO,"Using Unoptimized OnScreenDisplay\n"); #endif #endif //!CONFIG_RUNTIME_CPUDETECT } }
static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no) { unsigned int i, cell, last_cell; unsigned int t=0; ptt_info_t *ptt; pgc_t *pgc; if (!mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) return; title_no = tt_srpt->title[title_no].vts_ttn - 1; if(vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts < 2) return; ptt = vts_file->vts_ptt_srpt->title[title_no].ptt; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "CHAPTERS: "); for(i=0; i<vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts; i++) { int pgc_idx = ptt[i].pgcn-1; if (pgc_idx < 0 || pgc_idx >= vts_file->vts_pgcit->nr_of_pgci_srp) continue; pgc = vts_file->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc; if (!pgc) continue; cell = pgc->program_map[ptt[i].pgn-1]; //here the cell is 1-based if(ptt[i].pgn<pgc->nr_of_programs) last_cell = pgc->program_map[ptt[i].pgn]; else last_cell = 0; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "%02d:%02d:%02d.%03d,", t/3600000, (t/60000)%60, (t/1000)%60, t%1000); do { if(!(pgc->cell_playback[cell-1].block_type == BLOCK_TYPE_ANGLE_BLOCK && pgc->cell_playback[cell-1].block_mode != BLOCK_MODE_FIRST_CELL) ) t += mp_dvdtimetomsec(&pgc->cell_playback[cell-1].playback_time); cell++; } while(cell < last_cell); } mp_msg(MSGT_IDENTIFY, MSGL_INFO, "\n"); }
/** \brief Reads TOC from CD in the given device and prints the number of tracks and the length of each track in minute:second:frame format. \param *dev the device to analyse \return if the command line -identify is given, returns the last track of the TOC or -1 if the TOC can't be read, otherwise just returns 0 and let cddb_resolve the TOC */ int cdd_identify(const char *dev) { cdtoc_last_track = 0; if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) { int i, min, sec, frame; cdtoc_last_track = read_toc(dev); if (cdtoc_last_track < 0) { mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev); return -1; } mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_CDDA_TRACKS=%d\n", cdtoc_last_track); for (i = 1; i <= cdtoc_last_track; i++) { frame = cdtoc[i].frame - cdtoc[i-1].frame; sec = frame / 75; frame -= sec * 75; min = sec / 60; sec -= min * 60; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDA_TRACK_%d_MSF=%02d:%02d:%02d\n", i, min, sec, frame); } } return cdtoc_last_track; }
static int open_s(stream_t *stream, int mode) { int k; dvd_priv_t *d = stream->priv; MP_VERBOSE(stream, "URL: %s\n", stream->url); dvd_title = d->cfg_title + 1; if(1){ //int ret,ret2; int ttn,pgc_id,pgn; dvd_reader_t *dvd; dvd_file_t *title; ifo_handle_t *vmg_file; tt_srpt_t *tt_srpt; ifo_handle_t *vts_file; pgc_t *pgc; /** * Open the disc. */ if(d->cfg_device) dvd_device_current = d->cfg_device; else if(dvd_device) dvd_device_current = dvd_device; else dvd_device_current = DEFAULT_DVD_DEVICE; dvd_set_speed(stream,dvd_device_current, dvd_speed); #if defined(__APPLE__) || defined(__DARWIN__) /* Dynamic DVD drive selection on Darwin */ if(!strcmp(dvd_device_current, "/dev/rdiskN")) { int i; size_t len = strlen(dvd_device_current)+1; char *temp_device = malloc(len); for (i = 1; i < 10; i++) { snprintf(temp_device, len, "/dev/rdisk%d", i); dvd = DVDOpen(temp_device); if(!dvd) { MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",temp_device, strerror(errno)); } else { #if DVDREAD_VERSION <= LIBDVDREAD_VERSION(0,9,4) dvd_file_t *dvdfile = DVDOpenFile(dvd,dvd_title,DVD_READ_INFO_FILE); if(!dvdfile) { MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",temp_device, strerror(errno)); DVDClose(dvd); continue; } DVDCloseFile(dvdfile); #endif break; } } free(temp_device); if(!dvd) { return STREAM_UNSUPPORTED; } } else #endif /* defined(__APPLE__) || defined(__DARWIN__) */ { dvd = DVDOpen(dvd_device_current); if(!dvd) { MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",dvd_device_current, strerror(errno)); return STREAM_UNSUPPORTED; } } MP_VERBOSE(stream, "Reading disc structure, please wait...\n"); /** * Load the video manager to find out the information about the titles on * this disc. */ vmg_file = ifoOpen(dvd, 0); if(!vmg_file) { MP_ERR(stream, "Can't open VMG info!\n"); DVDClose( dvd ); return STREAM_UNSUPPORTED; } tt_srpt = vmg_file->tt_srpt; if (mp_msg_test(stream->log, MSGL_SMODE)) { int title_no; ///< title number MP_SMODE(stream, "ID_DVD_TITLES=%d\n", tt_srpt->nr_of_srpts); for (title_no = 0; title_no < tt_srpt->nr_of_srpts; title_no++) { MP_SMODE(stream, "ID_DVD_TITLE_%d_CHAPTERS=%d\n", title_no, tt_srpt->title[title_no].nr_of_ptts); MP_SMODE(stream, "ID_DVD_TITLE_%d_ANGLES=%d\n", title_no, tt_srpt->title[title_no].nr_of_angles); } } if (mp_msg_test(stream->log, MSGL_SMODE)) { char volid[32]; unsigned char discid [16]; ///< disk ID, a 128 bit MD5 sum int vts_no; ///< video title set number for (vts_no = 1; vts_no <= vmg_file->vts_atrt->nr_of_vtss; vts_no++) mp_describe_titleset(stream, dvd, tt_srpt, vts_no); if (DVDDiscID(dvd, discid) >= 0) { int i; MP_SMODE(stream, "ID_DVD_DISC_ID="); for (i = 0; i < 16; i ++) MP_SMODE(stream, "%02X", discid[i]); MP_SMODE(stream, "\n"); } if (DVDUDFVolumeInfo(dvd, volid, sizeof(volid), NULL, 0) >= 0 || DVDISOVolumeInfo(dvd, volid, sizeof(volid), NULL, 0) >= 0) MP_SMODE(stream, "ID_DVD_VOLUME_ID=%s\n", volid); } /** * Make sure our title number is valid. */ MP_INFO(stream, "There are %d titles on this DVD.\n", tt_srpt->nr_of_srpts ); if(dvd_title < 1 || dvd_title > tt_srpt->nr_of_srpts) { MP_ERR(stream, "Invalid DVD title number: %d\n", dvd_title); ifoClose( vmg_file ); DVDClose( dvd ); return STREAM_UNSUPPORTED; } MP_SMODE(stream, "ID_DVD_CURRENT_TITLE=%d\n", dvd_title); --dvd_title; // remap 1.. -> 0.. /** * Make sure the angle number is valid for this title. */ MP_INFO(stream, "There are %d angles in this DVD title.\n", tt_srpt->title[dvd_title].nr_of_angles); if(dvd_angle<1 || dvd_angle>tt_srpt->title[dvd_title].nr_of_angles) { MP_ERR(stream, "Invalid DVD angle number: %d\n", dvd_angle); goto fail; } ttn = tt_srpt->title[dvd_title].vts_ttn - 1; /** * Load the VTS information for the title set our title is in. */ vts_file = ifoOpen( dvd, tt_srpt->title[dvd_title].title_set_nr ); if(!vts_file) { MP_ERR(stream, "Cannot open the IFO file for DVD title %d.\n", tt_srpt->title[dvd_title].title_set_nr ); goto fail; } /** * We've got enough info, time to open the title set data. */ title = DVDOpenFile(dvd, tt_srpt->title[dvd_title].title_set_nr, DVD_READ_TITLE_VOBS); if(!title) { MP_ERR(stream, "Cannot open title VOBS (VTS_%02d_1.VOB).\n", tt_srpt->title[dvd_title].title_set_nr); ifoClose( vts_file ); goto fail; } MP_VERBOSE(stream, "DVD successfully opened.\n"); // store data d->dvd=dvd; d->title=title; d->vmg_file=vmg_file; d->tt_srpt=tt_srpt; d->vts_file=vts_file; d->cur_title = dvd_title; pgc = vts_file->vts_pgcit ? vts_file->vts_pgcit->pgci_srp[ttn].pgc : NULL; /** * Check number of audio channels and types */ { d->nr_of_channels=0; if(vts_file->vts_pgcit) { int i; for(i=0;i<8;i++) if(pgc->audio_control[i] & 0x8000) { audio_attr_t * audio = &vts_file->vtsi_mat->vts_audio_attr[i]; int language = 0; char tmp[] = "unknown"; stream_language_t *audio_stream = &d->audio_streams[d->nr_of_channels]; if(audio->lang_type == 1) { language=audio->lang_code; tmp[0]=language>>8; tmp[1]=language&0xff; tmp[2]=0; } audio_stream->language=language; audio_stream->id=pgc->audio_control[i] >> 8 & 7; switch(audio->audio_format) { case 0: // ac3 audio_stream->id+=FIRST_AC3_AID; break; case 6: // dts audio_stream->id+=FIRST_DTS_AID; break; case 2: // mpeg layer 1/2/3 case 3: // mpeg2 ext audio_stream->id+=FIRST_MPG_AID; break; case 4: // lpcm audio_stream->id+=FIRST_PCM_AID; break; } audio_stream->type=audio->audio_format; // Pontscho: to my mind, tha channels: // 1 - stereo // 5 - 5.1 audio_stream->channels=audio->channels; MP_INFO(stream, "audio stream: %d format: %s (%s) language: %s aid: %d.\n", d->nr_of_channels, dvd_audio_stream_types[ audio->audio_format ], dvd_audio_stream_channels[ audio->channels ], tmp, audio_stream->id ); MP_SMODE(stream, "ID_AUDIO_ID=%d\n", audio_stream->id); if(language && tmp[0]) MP_SMODE(stream, "ID_AID_%d_LANG=%s\n", audio_stream->id, tmp); d->nr_of_channels++; }
static uint32_t svga_draw_image(mp_image_t *mpi){ int i,x,y,w,h; int stride; uint8_t *rgbplane, *base; int bytesperline; int page; if(mpi->flags & MP_IMGFLAG_DIRECT){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: drawing direct rendered surface\n"); cpage=(uint32_t)mpi->priv; assert((cpage>=0)&&(cpage<max_pages)); return VO_TRUE; //it's already done } // if (mpi->flags&MP_IMGFLAGS_DRAWBACK) // return VO_TRUE;//direct render method 2 //find a free page to draw into //if there is no one then use the current one page = page_find_free(); if(page>=0) cpage=page; PageStore[cpage].locks=PAGE_BUSY; // these variables are used in loops x = mpi->x; y = mpi->y; w = mpi->w; h = mpi->h; stride = mpi->stride[0]; rgbplane = mpi->planes[0] + y*stride + (x*mpi->bpp)/8; x+=x_pos;//center y+=y_pos; if(mpi->bpp >= 8){//for modes<8 use only native if( (mode_capabilities&CAP_ACCEL_PUTIMAGE) && (x==0) && (w==mpi->width) && (stride == mode_stride) ){ //only monolite image can be accelerated w=(stride*8)/mpi->bpp;//we transfer pixels in the stride so the source //ACCELERATE if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using HW PutImage (x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); if(mode_capabilities & CAP_ACCEL_BACKGR) vga_accel(ACCEL_SYNC); vga_accel(ACCEL_PUTIMAGE,x,y+PageStore[cpage].yoffset,w,h,rgbplane); return VO_TRUE; } if( mode_capabilities&CAP_LINEAR){ //DIRECT if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using Direct memcpy (x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); bytesperline=(w*mpi->bpp)/8; base=PageStore[cpage].vbase + (y*mode_stride) + (x*mpi->bpp)/8; for(i=0;i<h;i++){ mem2agpcpy(base,rgbplane,bytesperline); base+=mode_stride; rgbplane+=stride; } return VO_TRUE; } }//(modebpp>=8 //NATIVE { int length; length=(w*mpi->bpp)/8; //one byte per pixel! svgalib innovation if(mpi->imgfmt==IMGFMT_RG4B || mpi->imgfmt==IMGFMT_BG4B) length=w; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using Native vga_draw(x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); y+=PageStore[cpage].yoffset;//y position of the page beggining for(i=0;i<h;i++){ vga_drawscansegment(rgbplane,x,y+i,length); rgbplane+=stride; } } return VO_TRUE; }
static int preinit(const char *arg) { int i; char s[64]; getch2_disable(); memset(zerobuf,0,sizeof(zerobuf)); force_vm=force_native=squarepix=0; sync_flip=vo_vsync; blackbar_osd=0; if(arg)while(*arg) { #ifdef CONFIG_VIDIX if(memcmp(arg,"vidix",5)==0) { i=6; while(arg[i] && arg[i]!=':') i++; strncpy(vidix_name, arg+6, i-6); vidix_name[i-5]=0; if(arg[i]==':')i++; arg+=i; vidix_preinit(vidix_name, &video_out_svga); } #endif if(!strncmp(arg,"sq",2)) { squarepix=1; arg+=2; if( *arg == ':' ) arg++; } if(!strncmp(arg,"native",6)) { force_native=1; arg+=6; if( *arg == ':' ) arg++; } if(!strncmp(arg,"bbosd",5)) { blackbar_osd=1; arg+=5; if( *arg == ':' ) arg++; } if(!strncmp(arg,"retrace",7)) { sync_flip=1; arg+=7; if( *arg == ':' ) arg++; } if(*arg) { i=0; while(arg[i] && arg[i]!=':')i++; if(i<64){ strncpy(s, arg, i); s[i]=0; force_vm=vga_getmodenumber(s); if(force_vm>0) { if( mp_msg_test(MSGT_VO,MSGL_V) ) mp_msg(MSGT_VO,MSGL_V, "vo_svga: Forcing mode %i\n",force_vm); }else{ force_vm = 0; } } arg+=i; if(*arg==':')arg++; } } vga_init(); return 0; }
int video_read_properties(sh_video_t *sh_video){ demux_stream_t *d_video=sh_video->ds; video_codec_t video_codec = find_video_codec(sh_video); // Determine image properties: switch(video_codec){ case VIDEO_OTHER: { if((d_video->demuxer->file_format == DEMUXER_TYPE_ASF) || (d_video->demuxer->file_format == DEMUXER_TYPE_AVI)) { // display info: // in case no strf chunk has been seen in avi, we have no bitmap header if(!sh_video->bih) return 0; sh_video->format=sh_video->bih->biCompression; sh_video->disp_w=sh_video->bih->biWidth; sh_video->disp_h=abs(sh_video->bih->biHeight); } break; } case VIDEO_MPEG4: { int pos = 0, vop_cnt=0, units[3]; videobuf_len=0; videobuf_code_len=0; mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Start code... "); while(1){ int i=sync_video_packet(d_video); if(i<=0x11F) break; // found it! if(!i || !skip_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); if(!videobuffer) { videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE); if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE); else { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Layer Start code... "); while(1){ int i=sync_video_packet(d_video); mp_msg(MSGT_DECVIDEO,MSGL_V,"M4V: 0x%X\n",i); if(i>=0x120 && i<=0x12F) break; // found it! if(!i || !read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } pos = videobuf_len+4; if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Layer Header\n"); return 0; } mp4_header_process_vol(&picture, &(videobuffer[pos])); mp_msg(MSGT_DECVIDEO,MSGL_V,"OK! FPS SEEMS TO BE %.3f\nSearching for Video Object Plane Start code... ", sh_video->fps); mp4_init: while(1){ int i=sync_video_packet(d_video); if(i==0x1B6) break; // found it! if(!i || !read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } pos = videobuf_len+4; if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Plane Header\n"); return 0; } mp4_header_process_vop(&picture, &(videobuffer[pos])); sh_video->disp_w = picture.display_picture_width; sh_video->disp_h = picture.display_picture_height; units[vop_cnt] = picture.timeinc_unit; vop_cnt++; //mp_msg(MSGT_DECVIDEO,MSGL_V, "TYPE: %d, unit: %d\n", picture.picture_type, picture.timeinc_unit); if(!picture.fps) { int i, mn, md, mx, diff; if(vop_cnt < 3) goto mp4_init; i=0; mn = mx = units[0]; for(i=0; i<3; i++) { if(units[i] < mn) mn = units[i]; if(units[i] > mx) mx = units[i]; } md = mn; for(i=0; i<3; i++) { if((units[i] > mn) && (units[i] < mx)) md = units[i]; } mp_msg(MSGT_DECVIDEO,MSGL_V, "MIN: %d, mid: %d, max: %d\n", mn, md, mx); if(mx - md > md - mn) diff = md - mn; else diff = mx - md; if(diff > 0){ picture.fps = ((float)picture.timeinc_resolution) / diff; mp_msg(MSGT_DECVIDEO,MSGL_V, "FPS seems to be: %f, resolution: %d, delta_units: %d\n", picture.fps, picture.timeinc_resolution, diff); } } if(picture.fps) { sh_video->fps=picture.fps; sh_video->frametime=1.0/picture.fps; mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps); } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); sh_video->format=0x10000004; break; } case VIDEO_H264: { int pos = 0; videobuf_len=0; videobuf_code_len=0; mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence parameter set... "); while(1){ int i=sync_video_packet(d_video); if((i&~0x60) == 0x107 && i != 0x107) break; // found it! if(!i || !skip_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); if(!videobuffer) { videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE); if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE); else { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); return 0; } } pos = videobuf_len+4; if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read sequence parameter set\n"); return 0; } h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos); sh_video->disp_w=picture.display_picture_width; sh_video->disp_h=picture.display_picture_height; mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for picture parameter set... "); while(1){ int i=sync_video_packet(d_video); mp_msg(MSGT_DECVIDEO,MSGL_V,"H264: 0x%X\n",i); if((i&~0x60) == 0x108 && i != 0x108) break; // found it! if(!i || !read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\nSearching for Slice... "); while(1){ int i=sync_video_packet(d_video); if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105) break; // found it! if(!i || !read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); sh_video->format=0x10000005; if(picture.fps) { sh_video->fps=picture.fps; sh_video->frametime=1.0/picture.fps; mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps); } break; } case VIDEO_MPEG12: { if (d_video->demuxer->file_format == DEMUXER_TYPE_ASF) { // DVR-MS if(!sh_video->bih) return 0; sh_video->format=sh_video->bih->biCompression; } mpeg_header_parser: // Find sequence_header first: videobuf_len=0; videobuf_code_len=0; telecine=0; telecine_cnt=-2.5; mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence header... "); while(1){ int i=sync_video_packet(d_video); if(i==0x1B3) break; // found it! if(!i || !skip_video_packet(d_video)){ if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_MpegNoSequHdr); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); // ========= Read & process sequence header & extension ============ if(!videobuffer) { videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE); if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE); else { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); return 0; } } if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdr); return 0; } if(mp_header_process_sequence_header (&picture, &videobuffer[4])) { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdr); goto mpeg_header_parser; } if(sync_video_packet(d_video)==0x1B5){ // next packet is seq. ext. int pos=videobuf_len; if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdrEx); return 0; } if(mp_header_process_extension (&picture, &videobuffer[pos+4])) { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdrEx); return 0; } } // display info: sh_video->format=picture.mpeg1?0x10000001:0x10000002; // mpeg video sh_video->fps=picture.fps * picture.frame_rate_extension_n / picture.frame_rate_extension_d; if(!sh_video->fps){ sh_video->frametime=0; } else { sh_video->frametime=1.0/sh_video->fps; } sh_video->disp_w=picture.display_picture_width; sh_video->disp_h=picture.display_picture_height; // bitrate: if(picture.bitrate!=0x3FFFF) // unspecified/VBR ? sh_video->i_bps=picture.bitrate * 400 / 8; // info: mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"mpeg bitrate: %d (%X)\n",picture.bitrate,picture.bitrate); mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: %s %dx%d (aspect %d) %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n", picture.mpeg1?"MPEG1":"MPEG2", sh_video->disp_w,sh_video->disp_h, picture.aspect_ratio_information, sh_video->fps, sh_video->i_bps * 8 / 1000.0, sh_video->i_bps / 1000.0 ); break; } case VIDEO_VC1: { // Find sequence_header: videobuf_len=0; videobuf_code_len=0; mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Searching for VC1 sequence header... "); while(1){ int i=sync_video_packet(d_video); if(i==0x10F) break; // found it! if(!i || !skip_video_packet(d_video)){ if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't find VC-1 sequence header\n"); return 0; } } mp_msg(MSGT_DECVIDEO,MSGL_INFO,"found\n"); if(!videobuffer) { videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE); if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE); else { mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); return 0; } } if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't read VC-1 sequence header!\n"); return 0; } while(1) { int i=sync_video_packet(d_video); if(i==0x10E) break; // found it! if(!i || !skip_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't find VC-1 entry point sync-code:(\n"); return 0; } } if(!read_video_packet(d_video)){ mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't read VC-1 entry point sync-code:(\n"); return 0; } if(mp_vc1_decode_sequence_header(&picture, &videobuffer[4], videobuf_len-4)) { sh_video->bih = calloc(1, sizeof(*sh_video->bih) + videobuf_len); if(sh_video->bih == NULL) { mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Couldn't alloc %d bytes for VC-1 extradata!\n", sizeof(*sh_video->bih) + videobuf_len); return 0; } sh_video->bih->biSize= sizeof(*sh_video->bih) + videobuf_len; memcpy(sh_video->bih + 1, videobuffer, videobuf_len); sh_video->bih->biCompression = sh_video->format; sh_video->bih->biWidth = sh_video->disp_w = picture.display_picture_width; sh_video->bih->biHeight = sh_video->disp_h = picture.display_picture_height; if(picture.fps > 0) { sh_video->frametime=1.0/picture.fps; sh_video->fps = picture.fps; } mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: VC-1 %dx%d, %5.3f fps, header len: %d\n", sh_video->disp_w, sh_video->disp_h, sh_video->fps, videobuf_len); } break; } } // switch(file_format) return 1; }
int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int preferred_outfmt) { int i, j; int only_preferred = 1; unsigned int out_fmt = 0; int screen_size_x = 0; //SCREEN_SIZE_X; int screen_size_y = 0; //SCREEN_SIZE_Y; vf_instance_t *vf = sh->vfilter, *sc = NULL; int palette = 0; int vocfg_flags = 0; if (w) sh->disp_w = w; if (h) sh->disp_h = h; if (!sh->disp_w || !sh->disp_h) return 0; mp_msg(MSGT_DECVIDEO, MSGL_V, "VDec: vo config request - %d x %d (preferred colorspace: %s)\n", w, h, vo_format_name(preferred_outfmt)); // if(!vf) return 1; // temp hack if (get_video_quality_max(sh) <= 0 && divx_quality) { // user wants postprocess but no pp filter yet: sh->vfilter = vf = vf_open_filter(vf, "pp", NULL); } // check if libvo and codec has common outfmt (no conversion): csp_again: if (mp_msg_test(MSGT_DECVIDEO, MSGL_V)) { vf_instance_t *f = vf; mp_msg(MSGT_DECVIDEO, MSGL_V, "Trying filter chain:"); for (f = vf; f; f = f->next) mp_msg(MSGT_DECVIDEO, MSGL_V, " %s", f->info->name); mp_msg(MSGT_DECVIDEO, MSGL_V, "\n"); } j = -1; for (i = 0; only_preferred || i < CODECS_MAX_OUTFMT; i++) { int flags; if (i == CODECS_MAX_OUTFMT) { i = 0; only_preferred = 0; } out_fmt = sh->codec->outfmt[i]; if (only_preferred && out_fmt != preferred_outfmt) continue; if (out_fmt == (unsigned int) 0xFFFFFFFF) continue; // check (query) if codec really support this outfmt... sh->outfmtidx = i; // pass index to the control() function this way if (mpvdec->control(sh, VDCTRL_QUERY_FORMAT, &out_fmt) == CONTROL_FALSE) { mp_msg(MSGT_CPLAYER, MSGL_DBG2, "vo_debug: codec query_format(%s) returned FALSE\n", vo_format_name(out_fmt)); continue; } flags = vf->query_format(vf, out_fmt); mp_msg(MSGT_CPLAYER, MSGL_DBG2, "vo_debug: query(%s) returned 0x%X (i=%d) \n", vo_format_name(out_fmt), flags, i); if ((flags & VFCAP_CSP_SUPPORTED_BY_HW) || (flags & VFCAP_CSP_SUPPORTED && j < 0)) { j = i; vo_flags = flags; if (flags & VFCAP_CSP_SUPPORTED_BY_HW) break; } else if (!palette && !(flags & (VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_CSP_SUPPORTED)) && (out_fmt == IMGFMT_RGB8 || out_fmt == IMGFMT_BGR8)) { palette = 1; } } if (j < 0 && !IMGFMT_IS_HWACCEL(preferred_outfmt)) { // TODO: no match - we should use conversion... if (strcmp(vf->info->name, "scale") && palette != -1) { mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_CouldNotFindColorspace); sc = vf = vf_open_filter(vf, "scale", NULL); goto csp_again; } else if (palette == 1) { mp_msg(MSGT_DECVIDEO, MSGL_V, "vd: Trying -vf palette...\n"); palette = -1; vf = vf_open_filter(vf, "palette", NULL); goto csp_again; } else { // sws failed, if the last filter (vf_vo) support MPEGPES try to append vf_lavc vf_instance_t *vo, *vp = NULL, *ve, *vpp = NULL; // Remove the scale filter if we added it ourselves if (vf == sc) { ve = vf; vf = vf->next; vf_uninit_filter(ve); } // Find the last filter (vf_vo) for (vo = vf; vo->next; vo = vo->next) { vpp = vp; vp = vo; } if (vo->query_format(vo, IMGFMT_MPEGPES) && (!vp || (vp && strcmp(vp->info->name, "lavc")))) { ve = vf_open_filter(vo, "lavc", NULL); if (vp) vp->next = ve; else vf = ve; goto csp_again; } if (vp && !strcmp(vp->info->name, "lavc")) { if (vpp) vpp->next = vo; else vf = vo; vf_uninit_filter(vp); } } } if (j < 0) { mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_VOincompCodec); sh->vf_initialized = -1; return 0; // failed } out_fmt = sh->codec->outfmt[j]; mp_msg(MSGT_CPLAYER, MSGL_V, "VDec: using %s as output csp (no %d)\n", vo_format_name(out_fmt), j); sh->outfmtidx = j; sh->vfilter = vf; // autodetect flipping if (flip == -1) { flip = 0; if (sh->codec->outflags[j] & CODECS_FLAG_FLIP) if (!(sh->codec->outflags[j] & CODECS_FLAG_NOFLIP)) flip = 1; } if (vo_flags & VFCAP_FLIPPED) flip ^= 1; flip ^= sh->flipped_input; if (flip && !(vo_flags & VFCAP_FLIP)) { // we need to flip, but no flipping filter avail. vf_add_before_vo(&vf, "flip", NULL); sh->vfilter = vf; } // time to do aspect ratio corrections... if (movie_aspect > -1.0) sh->aspect = movie_aspect; // cmdline overrides autodetect else if (sh->stream_aspect != 0.0) sh->aspect = sh->stream_aspect; else sh->aspect = sh->original_aspect; if (opt_screen_size_x || opt_screen_size_y) { screen_size_x = opt_screen_size_x; screen_size_y = opt_screen_size_y; if (!vidmode) { if (!screen_size_x) screen_size_x = SCREEN_SIZE_X; if (!screen_size_y) screen_size_y = SCREEN_SIZE_Y; if (screen_size_x <= 8) screen_size_x *= sh->disp_w; if (screen_size_y <= 8) screen_size_y *= sh->disp_h; } } else { // check source format aspect, calculate prescale ::atmos screen_size_x = sh->disp_w; screen_size_y = sh->disp_h; if (screen_size_xy >= 0.001) { if (screen_size_xy <= 8) { // -xy means x+y scale screen_size_x *= screen_size_xy; screen_size_y *= screen_size_xy; } else { // -xy means forced width while keeping correct aspect screen_size_x = screen_size_xy; screen_size_y = screen_size_xy * sh->disp_h / sh->disp_w; } } if (sh->aspect >= 0.01) { int w; mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_MovieAspectIsSet, sh->aspect); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect); w = (int) ((float) screen_size_y * sh->aspect); w += w % 2; // round // we don't like horizontal downscale || user forced width: if (w < screen_size_x || screen_size_xy > 8) { screen_size_y = (int) ((float) screen_size_x * (1.0 / sh->aspect)); screen_size_y += screen_size_y % 2; // round } else screen_size_x = w; // keep new width } else { mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_MovieAspectUndefined); } } vocfg_flags = (fullscreen ? VOFLAG_FULLSCREEN : 0) | (vidmode ? VOFLAG_MODESWITCHING : 0) | (softzoom ? VOFLAG_SWSCALE : 0) | (flip ? VOFLAG_FLIPPING : 0); // Time to config libvo! mp_msg(MSGT_CPLAYER, MSGL_V, "VO Config (%dx%d->%dx%d,flags=%d,'%s',0x%X)\n", sh->disp_w, sh->disp_h, screen_size_x, screen_size_y, vocfg_flags, "MPlayer", out_fmt); vf->w = sh->disp_w; vf->h = sh->disp_h; if (vf_config_wrapper (vf, sh->disp_w, sh->disp_h, screen_size_x, screen_size_y, vocfg_flags, out_fmt) == 0) { // "MPlayer",out_fmt)){ mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_CannotInitVO); sh->vf_initialized = -1; return 0; } sh->vf_initialized = 1; if (vo_gamma_gamma != 1000) set_video_colors(sh, "gamma", vo_gamma_gamma); if (vo_gamma_brightness != 1000) set_video_colors(sh, "brightness", vo_gamma_brightness); if (vo_gamma_contrast != 1000) set_video_colors(sh, "contrast", vo_gamma_contrast); if (vo_gamma_saturation != 1000) set_video_colors(sh, "saturation", vo_gamma_saturation); if (vo_gamma_hue != 1000) set_video_colors(sh, "hue", vo_gamma_hue); return 1; }
int vidix_init(unsigned src_width,unsigned src_height, unsigned x_org,unsigned y_org,unsigned dst_width, unsigned dst_height,unsigned format,unsigned dest_bpp, unsigned vid_w,unsigned vid_h) { void *tmp, *tmpa; size_t i; int err; uint32_t sstride,apitch; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) mp_msg(MSGT_VO,MSGL_DBG2, "vosub_vidix: vidix_init() was called\n" "src_w=%u src_h=%u dest_x_y_w_h = %u %u %u %u\n" "format=%s dest_bpp=%u vid_w=%u vid_h=%u\n" ,src_width,src_height,x_org,y_org,dst_width,dst_height ,vo_format_name(format),dest_bpp,vid_w,vid_h); if(vidix_query_fourcc(format) == 0) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_UnsupportedFourccForThisVidixDriver, format,vo_format_name(format)); return -1; } if(((vidix_cap.maxwidth != -1) && (vid_w > vidix_cap.maxwidth)) || ((vidix_cap.minwidth != -1) && (vid_w < vidix_cap.minwidth)) || ((vidix_cap.maxheight != -1) && (vid_h > vidix_cap.maxheight)) || ((vidix_cap.minwidth != -1 ) && (vid_h < vidix_cap.minheight))) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedResolution, vid_w, vid_h, vidix_cap.minwidth, vidix_cap.minheight, vidix_cap.maxwidth, vidix_cap.maxheight); return -1; } err = 0; switch(dest_bpp) { case 1: err = ((vidix_fourcc.depth & VID_DEPTH_1BPP) != VID_DEPTH_1BPP); break; case 2: err = ((vidix_fourcc.depth & VID_DEPTH_2BPP) != VID_DEPTH_2BPP); break; case 4: err = ((vidix_fourcc.depth & VID_DEPTH_4BPP) != VID_DEPTH_4BPP); break; case 8: err = ((vidix_fourcc.depth & VID_DEPTH_8BPP) != VID_DEPTH_8BPP); break; case 12:err = ((vidix_fourcc.depth & VID_DEPTH_12BPP) != VID_DEPTH_12BPP); break; case 15:err = ((vidix_fourcc.depth & VID_DEPTH_15BPP) != VID_DEPTH_15BPP); break; case 16:err = ((vidix_fourcc.depth & VID_DEPTH_16BPP) != VID_DEPTH_16BPP); break; case 24:err = ((vidix_fourcc.depth & VID_DEPTH_24BPP) != VID_DEPTH_24BPP); break; case 32:err = ((vidix_fourcc.depth & VID_DEPTH_32BPP) != VID_DEPTH_32BPP); break; default: err=1; break; } if(err) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedColorDepth ,vidix_fourcc.depth); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_UPSCALER) != FLAG_UPSCALER) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantUpscaleImage, src_width, src_height, dst_width, dst_height); return -1; } if((dst_width > src_width || dst_height > src_height) && (vidix_cap.flags & FLAG_DOWNSCALER) != FLAG_DOWNSCALER) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_DriverCantDownscaleImage, src_width, src_height, dst_width, dst_height); return -1; } image_width = src_width; image_height = src_height; src_format = format; if(forced_fourcc) format = forced_fourcc; memset(&vidix_play,0,sizeof(vidix_playback_t)); vidix_play.fourcc = format; vidix_play.capability = vidix_cap.flags; /* every ;) */ vidix_play.blend_factor = 0; /* for now */ /* display the full picture. Nick: we could implement here zooming to a specified area -- alex */ vidix_play.src.x = vidix_play.src.y = 0; vidix_play.src.w = src_width; vidix_play.src.h = src_height; vidix_play.dest.x = x_org; vidix_play.dest.y = y_org; vidix_play.dest.w = dst_width; vidix_play.dest.h = dst_height; // vidix_play.num_frames=vo_doublebuffering?NUM_FRAMES-1:1; /* we aren't mad...3 buffers are more than enough */ vidix_play.num_frames=vo_doublebuffering?3:1; vidix_play.src.pitch.y = vidix_play.src.pitch.u = vidix_play.src.pitch.v = 0; if((err=vdlConfigPlayback(vidix_handler,&vidix_play))!=0) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SUB_VIDIX_CantConfigurePlayback,strerror(err)); return -1; } if ( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vosub_vidix: using %d buffer(s)\n", vidix_play.num_frames); } vidix_mem = vidix_play.dga_addr; tmp = calloc(image_width, image_height); tmpa = malloc(image_width * image_height); memset(tmpa, 1, image_width * image_height); /* clear every frame with correct address and frame_size */ /* HACK: use draw_alpha to clear Y component */ for (i = 0; i < vidix_play.num_frames; i++) { next_frame = i; memset(vidix_mem + vidix_play.offsets[i], 0x80, vidix_play.frame_size); draw_alpha(0, 0, image_width, image_height, tmp, tmpa, image_width); } free(tmp); free(tmpa); /* show one of the "clear" frames */ vidix_flip_page(); switch(format) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_Y800: case IMGFMT_Y8: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width + apitch) & ~apitch; apitch = vidix_play.dest.pitch.v-1; dstrides.v = (image_width + apitch) & ~apitch; apitch = vidix_play.dest.pitch.u-1; dstrides.u = (image_width + apitch) & ~apitch; image_Bpp=1; break; case IMGFMT_RGB32: case IMGFMT_BGR32: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*4 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=4; break; case IMGFMT_RGB24: case IMGFMT_BGR24: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*3 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=3; break; default: apitch = vidix_play.dest.pitch.y-1; dstrides.y = (image_width*2 + apitch) & ~apitch; dstrides.u = dstrides.v = 0; image_Bpp=2; break; } /* tune some info here */ sstride = src_width*image_Bpp; if(!forced_fourcc) { is_422_planes_eq = sstride == dstrides.y; if(src_format == IMGFMT_YV12 || src_format == IMGFMT_I420 || src_format == IMGFMT_IYUV) vo_server->draw_slice = vidix_draw_slice_420; else if (src_format == IMGFMT_YVU9 || src_format == IMGFMT_IF09) vo_server->draw_slice = vidix_draw_slice_410; else vo_server->draw_slice = vidix_draw_slice_packed; } return 0; }
// init driver static int init(sh_video_t *sh){ HRESULT ret; // unsigned int outfmt=sh->codec->outfmt[sh->outfmtidx]; int i, o_bih_len; vd_vfw_ctx *priv; const char *dll = codec_idx2str(sh->codec->dll_idx); /* Hack for VSSH codec: new dll can't decode old files * In my samples old files have no extradata, so use that info * to decide what dll should be used (here and in vd_dshow). */ if (!strcmp(dll, "vssh264.dll") && (sh->bih->biSize > 40)) return 0; priv = malloc(sizeof(vd_vfw_ctx)); if (!priv) return 0; memset(priv, 0, sizeof(vd_vfw_ctx)); sh->context = priv; mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Codec init =======\n"); // win32_codec_name = dll; // sh->hic = ICOpen( 0x63646976, sh->bih->biCompression, ICMODE_FASTDECOMPRESS); // priv->handle = ICOpen( 0x63646976, sh->bih->biCompression, ICMODE_DECOMPRESS); priv->handle = ICOpen( (long)(dll), sh->bih->biCompression, ICMODE_DECOMPRESS); if(!priv->handle){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n"); return 0; } // sh->bih->biBitCount=32; o_bih_len = ICDecompressGetFormatSize(priv->handle, sh->bih); if(o_bih_len < sizeof(BITMAPINFOHEADER)){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICDecompressGetFormatSize returned a bogus value: %d\n", o_bih_len); return 0; } priv->o_bih = malloc(o_bih_len); memset(priv->o_bih, 0, o_bih_len); mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetFormatSize ret: %d\n", o_bih_len); ret = ICDecompressGetFormat(priv->handle, sh->bih, priv->o_bih); if(ret < 0){ mp_msg(MSGT_WIN32,MSGL_ERR,"ICDecompressGetFormat failed: Error %d\n", (int)ret); for (i=0; i < o_bih_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", priv->o_bih[i]); return 0; } mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetFormat OK\n"); #if 0 // workaround for pegasus MJPEG: if(!sh_video->o_bih.biWidth) sh_video->o_bih.biWidth=sh_video->bih->biWidth; if(!sh_video->o_bih.biHeight) sh_video->o_bih.biHeight=sh_video->bih->biHeight; if(!sh_video->o_bih.biPlanes) sh_video->o_bih.biPlanes=sh_video->bih->biPlanes; #endif // ok let libvo and vd core to handshake and decide the optimal csp: if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_YUY2)) return 0; if (!(sh->codec->outflags[sh->outfmtidx]&CODECS_FLAG_FLIP)) { priv->o_bih->biHeight=-sh->bih->biHeight; // flip image! } // ok, let's set the choosen colorspace: set_csp(priv->o_bih,sh->codec->outfmt[sh->outfmtidx]); // fake it to RGB for broken DLLs (divx3) if(sh->codec->outflags[sh->outfmtidx] & CODECS_FLAG_YUVHACK) priv->o_bih->biCompression = 0; // sanity check: #ifdef BUILD_VFWEX ret = ICDecompressQueryEx(priv->handle, sh->bih, priv->o_bih); #else ret = ICDecompressQuery(priv->handle, sh->bih, priv->o_bih); #endif if (ret) { mp_msg(MSGT_WIN32,MSGL_WARN,"ICDecompressQuery failed: Error %d\n", (int)ret); // return 0; } else mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressQuery OK\n"); #ifdef BUILD_VFWEX ret = ICDecompressBeginEx(priv->handle, sh->bih, priv->o_bih); #else ret = ICDecompressBegin(priv->handle, sh->bih, priv->o_bih); #endif if (ret) { mp_msg(MSGT_WIN32,MSGL_WARN,"ICDecompressBegin failed: Error %d\n", (int)ret); // return 0; } // for broken codecs set it again: if(sh->codec->outflags[sh->outfmtidx] & CODECS_FLAG_YUVHACK) set_csp(priv->o_bih,sh->codec->outfmt[sh->outfmtidx]); mp_msg(MSGT_WIN32, MSGL_V, "Input format:\n"); if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh->bih,MSGL_V); mp_msg(MSGT_WIN32, MSGL_V, "Output format:\n"); if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(priv->o_bih,MSGL_V); // set postprocessing level in xvid/divx4 .dll ICSendMessage(priv->handle, ICM_USER+80, (long)(&divx_quality), 0); // don't do this palette mess always, it makes div3 dll crashing... if(sh->codec->outfmt[sh->outfmtidx]==IMGFMT_BGR8){ if(ICDecompressGetPalette(priv->handle, sh->bih, priv->o_bih)){ priv->palette = (unsigned char*)(priv->o_bih+1); mp_msg(MSGT_WIN32,MSGL_V,"ICDecompressGetPalette OK\n"); } else { if(sh->bih->biSize>=40+4*4) priv->palette = (unsigned char*)(sh->bih+1); } } mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32 video codec init OK!\n"); return 1; }
static int preinit(sh_audio_t *sh_audio) { HRESULT ret; WAVEFORMATEX *in_fmt = sh_audio->wf; DWORD srcsize = 0; acm_context_t *priv; priv = malloc(sizeof(acm_context_t)); if (!priv) return 0; sh_audio->context = priv; mp_msg(MSGT_WIN32, MSGL_V, "======= Win32 (ACM) AUDIO Codec init =======\n"); // priv->handle = NULL; priv->o_wf = malloc(sizeof(*priv->o_wf)); if (!priv->o_wf) { mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror); return 0; } priv->o_wf->nChannels = in_fmt->nChannels; priv->o_wf->nSamplesPerSec = in_fmt->nSamplesPerSec; priv->o_wf->nAvgBytesPerSec = 2*in_fmt->nSamplesPerSec*in_fmt->nChannels; priv->o_wf->wFormatTag = WAVE_FORMAT_PCM; priv->o_wf->nBlockAlign = 2*in_fmt->nChannels; priv->o_wf->wBitsPerSample = 16; // priv->o_wf->wBitsPerSample = inf_fmt->wBitsPerSample; priv->o_wf->cbSize = 0; if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) { mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n"); print_wave_header(in_fmt, MSGL_V); mp_msg(MSGT_DECAUDIO, MSGL_V, "Output format:\n"); print_wave_header(priv->o_wf, MSGL_V); } MSACM_RegisterDriver((const char *)sh_audio->codec->dll, in_fmt->wFormatTag, 0); ret = acmStreamOpen(&priv->handle, (HACMDRIVER)NULL, in_fmt, priv->o_wf, NULL, 0, 0, 0); if (ret) { if (ret == ACMERR_NOTPOSSIBLE) mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: Unappropriate audio format\n"); else mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: acmStreamOpen error: %d\n", (int)ret); mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror); return 0; } mp_msg(MSGT_WIN32, MSGL_V, "Audio codec opened OK! ;-)\n"); acmStreamSize(priv->handle, in_fmt->nBlockAlign, &srcsize, ACM_STREAMSIZEF_SOURCE); //if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) printf("Audio ACM output buffer min. size: %ld (reported by codec)\n", srcsize); srcsize *= 2; //if (srcsize < MAX_OUTBURST) srcsize = MAX_OUTBURST; if (!srcsize) { mp_msg(MSGT_WIN32, MSGL_WARN, "Warning! ACM codec reports srcsize=0\n"); srcsize = 16384; } // limit srcsize to 4-16kb //while(srcsize && srcsize<4096) srcsize*=2; //while(srcsize>16384) srcsize/=2; sh_audio->audio_out_minsize=srcsize; // audio output min. size mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM output buffer min. size: %ld\n",srcsize); acmStreamSize(priv->handle, srcsize, &srcsize, ACM_STREAMSIZEF_DESTINATION); // if(srcsize<in_fmt->nBlockAlign) srcsize=in_fmt->nBlockAlign; if (!srcsize) { mp_msg(MSGT_WIN32, MSGL_WARN, "Warning! ACM codec reports srcsize=0\n"); srcsize = 2*in_fmt->nBlockAlign; } mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM input buffer min. size: %ld\n",srcsize); sh_audio->audio_in_minsize=2*srcsize; // audio input min. size sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; sh_audio->channels=priv->o_wf->nChannels; sh_audio->samplerate=priv->o_wf->nSamplesPerSec; sh_audio->samplesize=2; mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/ACM audio codec init OK!\n"); return 1; }
int ai_alsa_setup(audio_in_t *ai) { snd_pcm_hw_params_t *params; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t buffer_size, period_size; int err; int dir; unsigned int rate; snd_pcm_hw_params_alloca(¶ms); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_hw_params_any(ai->alsa.handle, params); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Broken configuration for this PCM: no configurations available.\n"); return -1; } err = snd_pcm_hw_params_set_access(ai->alsa.handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Access type not available.\n"); return -1; } err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16_LE); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Sample format not available.\n"); return -1; } err = snd_pcm_hw_params_set_channels(ai->alsa.handle, params, ai->req_channels); if (err < 0) { snd_pcm_hw_params_get_channels(params, &ai->channels); mp_tmsg(MSGT_TV, MSGL_ERR, "Channel count not available - reverting to default: %d\n", ai->channels); } else { ai->channels = ai->req_channels; } dir = 0; rate = ai->req_samplerate; err = snd_pcm_hw_params_set_rate_near(ai->alsa.handle, params, &rate, &dir); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set samplerate.\n"); } ai->samplerate = rate; dir = 0; ai->alsa.buffer_time = 1000000; err = snd_pcm_hw_params_set_buffer_time_near(ai->alsa.handle, params, &ai->alsa.buffer_time, &dir); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set buffer time.\n"); } dir = 0; ai->alsa.period_time = ai->alsa.buffer_time / 4; err = snd_pcm_hw_params_set_period_time_near(ai->alsa.handle, params, &ai->alsa.period_time, &dir); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set period time.\n"); } err = snd_pcm_hw_params(ai->alsa.handle, params); if (err < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Unable to install hardware parameters: %s", snd_strerror(err)); snd_pcm_hw_params_dump(params, ai->alsa.log); return -1; } dir = -1; snd_pcm_hw_params_get_period_size(params, &period_size, &dir); snd_pcm_hw_params_get_buffer_size(params, &buffer_size); ai->alsa.chunk_size = period_size; if (period_size == buffer_size) { mp_tmsg(MSGT_TV, MSGL_ERR, "Can't use period equal to buffer size (%u == %lu)\n", ai->alsa.chunk_size, (long)buffer_size); return -1; } snd_pcm_sw_params_current(ai->alsa.handle, swparams); err = snd_pcm_sw_params_set_avail_min(ai->alsa.handle, swparams, ai->alsa.chunk_size); err = snd_pcm_sw_params_set_start_threshold(ai->alsa.handle, swparams, 0); err = snd_pcm_sw_params_set_stop_threshold(ai->alsa.handle, swparams, buffer_size); if (snd_pcm_sw_params(ai->alsa.handle, swparams) < 0) { mp_tmsg(MSGT_TV, MSGL_ERR, "Unable to install software parameters:\n"); snd_pcm_sw_params_dump(swparams, ai->alsa.log); return -1; } if (mp_msg_test(MSGT_TV, MSGL_V)) { snd_pcm_dump(ai->alsa.handle, ai->alsa.log); } ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE); ai->alsa.bits_per_frame = ai->alsa.bits_per_sample * ai->channels; ai->blocksize = ai->alsa.chunk_size * ai->alsa.bits_per_frame / 8; ai->samplesize = ai->alsa.bits_per_sample; ai->bytes_per_sample = ai->alsa.bits_per_sample/8; return 0; }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ OSErr cres; long framesizemax; UInt8 similarity=0; long compressedsize; OSType in_format=kYUVSPixelFormat; int width = mpi->width; int height = mpi->height; int stride = width*2; if(!codec_initialized){ FrameRect.top=0; FrameRect.left=0; FrameRect.right=width; FrameRect.bottom=height; cres = QTNewGWorldFromPtr( &frame_GWorld_in, in_format, &FrameRect, 0, 0, 0, mpi->planes[0], stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); //dunno what todo about this frame_prev = malloc(stride * height); cres = QTNewGWorldFromPtr( &frame_GWorld_prev, in_format, &FrameRect, 0, 0, 0, frame_prev, stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"height:%i width:%i stride:%i\n",height,width,stride); mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); cres= GetMaxCompressionSize ( GetGWorldPixMap(frame_GWorld_in), &FrameRect, 24, codecNormalQuality, bswap_32(format), compressor, &framesizemax ); mp_msg(MSGT_MENCODER,MSGL_DBG2,"GetMaxCompressionSize returned:%i : MaxSize:%li\n",cres&0xFFFF,framesizemax); frame_comp=malloc(framesizemax); desc = (ImageDescriptionHandle)NewHandleClear(MAX_IDSIZE); //memory where the desc will be stored (*desc)->idSize=MAX_IDSIZE; cres= CompressSequenceBegin ( &seq, GetGWorldPixMap( frame_GWorld_in), GetGWorldPixMap( frame_GWorld_prev), &FrameRect, &FrameRect, 24, // color depth bswap_32(format), // fourcc compressor, // codec component codecNormalQuality, //codecNormalQuality, codecMaxQuality, //codecNormalQuality, 10*30, // keyframe rate 0, 0, desc); mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceBegin returned:%i\n",cres&0xFFFF); mp_msg(MSGT_MENCODER,MSGL_DBG2,"Sequence ID:%i\n",seq); if (mp_msg_test(MSGT_MENCODER, MSGL_DBG2)) dump_ImageDescription(*desc); codec_initialized++; } cres = CompressSequenceFrame ( seq, GetGWorldPixMap(frame_GWorld_in), &FrameRect, 0, (char*)mux_v->buffer, &compressedsize, &similarity, 0); if(cres&0xFFFF)mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceFrame returned:%i\n",cres&0xFFFF); #if 0 printf("Size %i->%i \n",stride*height,compressedsize); printf("Ratio: %i:1\n",(stride*height)/compressedsize); #endif muxer_write_chunk(mux_v, compressedsize , similarity?0:0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); if(((*desc)->idSize)>MAX_IDSIZE){ mp_msg(MSGT_MENCODER,MSGL_ERR,"FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc)->idSize)); } else { // according to QT docs, imagedescription may be changed while encoding // a frame (even its size may (and does!) change!) memcpy(mux_v->bih+1,*desc,(*desc)->idSize); } return 1; }