📄 dmo.c
字号:
p_enc->fmt_out.i_bitrate * 110 / 800 /* + 10% */ && p_wf->nAvgBytesPerSec > i_last_byterate ) { i_selected = i - 1; i_last_byterate = p_wf->nAvgBytesPerSec; msg_Dbg( p_enc, "selected entry %i (bitrate: %i)", i_selected, p_wf->nAvgBytesPerSec * 8 ); } } DMOFreeMediaType( &dmo_type ); } if( i_selected < 0 ) { msg_Err( p_enc, "couldn't find a matching ouput" ); return VLC_EGENERIC; } p_dmo->vt->GetOutputType( p_dmo, 0, i_selected, &dmo_type ); p_wf = (WAVEFORMATEX *)dmo_type.pbFormat; msg_Dbg( p_enc, "selected format: %i, sample rate:%i, " "channels: %i, bits per sample: %i, bitrate: %i, blockalign: %i", (int)p_wf->wFormatTag, (int)p_wf->nSamplesPerSec, (int)p_wf->nChannels, (int)p_wf->wBitsPerSample, (int)p_wf->nAvgBytesPerSec * 8, (int)p_wf->nBlockAlign ); p_enc->fmt_out.audio.i_rate = p_wf->nSamplesPerSec; p_enc->fmt_out.audio.i_channels = p_wf->nChannels; p_enc->fmt_out.audio.i_bitspersample = p_wf->wBitsPerSample; p_enc->fmt_out.audio.i_blockalign = p_wf->nBlockAlign; p_enc->fmt_out.i_bitrate = p_wf->nAvgBytesPerSec * 8; if( p_wf->cbSize ) { msg_Dbg( p_enc, "found cbSize: %i", p_wf->cbSize ); p_enc->fmt_out.i_extra = p_wf->cbSize; p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra ); memcpy( p_enc->fmt_out.p_extra, &p_wf[1], p_enc->fmt_out.i_extra ); } i_err = p_dmo->vt->SetOutputType( p_dmo, 0, &dmo_type, 0 ); DMOFreeMediaType( &dmo_type ); if( i_err ) { msg_Err( p_enc, "can't set DMO output type: %i", i_err ); return VLC_EGENERIC; } msg_Dbg( p_enc, "successfully set output type" ); /* Setup the input type */ i = 0; i_selected = -1; while( !p_dmo->vt->GetInputType( p_dmo, 0, i++, &dmo_type ) ) { p_wf = (WAVEFORMATEX *)dmo_type.pbFormat; msg_Dbg( p_enc, "available format :%i, sample rate: %i, channels: %i, " "bits per sample: %i, bitrate: %i, blockalign: %i", (int) p_wf->wFormatTag, (int)p_wf->nSamplesPerSec, (int)p_wf->nChannels, (int)p_wf->wBitsPerSample, (int)p_wf->nAvgBytesPerSec * 8, (int)p_wf->nBlockAlign ); if( p_wf->wFormatTag == WAVE_FORMAT_PCM && p_wf->nSamplesPerSec == p_enc->fmt_in.audio.i_rate && p_wf->nChannels == p_enc->fmt_in.audio.i_channels && p_wf->wBitsPerSample == p_enc->fmt_in.audio.i_bitspersample ) { i_selected = i - 1; } DMOFreeMediaType( &dmo_type ); } if( i_selected < 0 ) { msg_Err( p_enc, "couldn't find a matching input" ); return VLC_EGENERIC; } p_dmo->vt->GetInputType( p_dmo, 0, i_selected, &dmo_type ); i_err = p_dmo->vt->SetInputType( p_dmo, 0, &dmo_type, 0 ); DMOFreeMediaType( &dmo_type ); if( i_err ) { msg_Err( p_enc, "can't set DMO input type: %x", i_err ); return VLC_EGENERIC; } msg_Dbg( p_enc, "successfully set input type" ); return VLC_SUCCESS;}/***************************************************************************** * EncOpen: open dmo codec *****************************************************************************/static int EncOpen( vlc_object_t *p_this ){ encoder_t *p_enc = (encoder_t*)p_this; encoder_sys_t *p_sys = NULL; IMediaObject *p_dmo = NULL; HINSTANCE hmsdmo_dll = NULL;#ifdef LOADER ldt_fs_t *ldt_fs = Setup_LDT_Keeper();#else /* Initialize OLE/COM */ CoInitialize( 0 );#endif /* LOADER */ if( LoadDMO( p_this, &hmsdmo_dll, &p_dmo, &p_enc->fmt_out, VLC_TRUE ) != VLC_SUCCESS ) { hmsdmo_dll = 0; p_dmo = 0; goto error; } if( p_enc->fmt_in.i_cat == VIDEO_ES ) { if( EncoderSetVideoType( p_enc, p_dmo ) != VLC_SUCCESS ) goto error; } else { if( EncoderSetAudioType( p_enc, p_dmo ) != VLC_SUCCESS ) goto error; } /* Allocate the memory needed to store the decoder's structure */ if( ( p_enc->p_sys = p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) { msg_Err( p_enc, "out of memory" ); goto error; } p_sys->hmsdmo_dll = hmsdmo_dll; p_sys->p_dmo = p_dmo;#ifdef LOADER p_sys->ldt_fs = ldt_fs;#endif /* Find out some properties of the inputput */ { uint32_t i_size, i_align, dum; if( p_dmo->vt->GetInputSizeInfo( p_dmo, 0, &i_size, &i_align, &dum ) ) msg_Err( p_enc, "GetInputSizeInfo() failed" ); else msg_Dbg( p_enc, "GetInputSizeInfo(): bytes %i, align %i, %i", i_size, i_align, dum ); } /* Find out some properties of the output */ { uint32_t i_size, i_align; p_sys->i_min_output = 0; if( p_dmo->vt->GetOutputSizeInfo( p_dmo, 0, &i_size, &i_align ) ) { msg_Err( p_enc, "GetOutputSizeInfo() failed" ); goto error; } else { msg_Dbg( p_enc, "GetOutputSizeInfo(): bytes %i, align %i", i_size, i_align ); p_sys->i_min_output = i_size; } } /* Set output properties */ p_enc->fmt_out.i_cat = p_enc->fmt_out.i_cat; if( p_enc->fmt_out.i_cat == AUDIO_ES ) date_Init( &p_sys->end_date, p_enc->fmt_out.audio.i_rate, 1 ); else date_Init( &p_sys->end_date, 25 /* FIXME */, 1 ); return VLC_SUCCESS; error: if( p_dmo ) p_dmo->vt->Release( (IUnknown *)p_dmo ); if( hmsdmo_dll ) FreeLibrary( hmsdmo_dll );#ifdef LOADER Restore_LDT_Keeper( ldt_fs );#else /* Uninitialize OLE/COM */ CoUninitialize();#endif /* LOADER */ if( p_sys ) free( p_sys ); return VLC_EGENERIC;}/**************************************************************************** * Encode: the whole thing ****************************************************************************/static block_t *EncodeBlock( encoder_t *p_enc, void *p_data ){ encoder_sys_t *p_sys = p_enc->p_sys; CMediaBuffer *p_in; block_t *p_chain = NULL; block_t *p_block_in; uint32_t i_status; int i_result; mtime_t i_pts; if( p_sys == NULL ) { if( EncOpen( VLC_OBJECT(p_enc) ) ) { msg_Err( p_enc, "EncOpen failed" ); return NULL; } p_sys = p_enc->p_sys; } if( !p_data ) return NULL; if( p_enc->fmt_out.i_cat == VIDEO_ES ) { /* Get picture data */ int i_plane, i_line, i_width, i_src_stride; picture_t *p_pic = (picture_t *)p_data; uint8_t *p_dst; int i_buffer = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * p_enc->fmt_in.video.i_bits_per_pixel / 8; p_block_in = block_New( p_enc, i_buffer ); /* Copy picture stride by stride */ p_dst = p_block_in->p_buffer; for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) { uint8_t *p_src = p_pic->p[i_plane].p_pixels; i_width = p_pic->p[i_plane].i_visible_pitch; i_src_stride = p_pic->p[i_plane].i_pitch; for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ ) { p_enc->p_vlc->pf_memcpy( p_dst, p_src, i_width ); p_dst += i_width; p_src += i_src_stride; } } i_pts = p_pic->date; } else { aout_buffer_t *p_aout_buffer = (aout_buffer_t *)p_data; p_block_in = block_New( p_enc, p_aout_buffer->i_nb_bytes ); memcpy( p_block_in->p_buffer, p_aout_buffer->p_buffer, p_block_in->i_buffer ); i_pts = p_aout_buffer->start_date; } /* Feed input to the DMO */ p_in = CMediaBufferCreate( p_block_in, p_block_in->i_buffer, VLC_TRUE ); i_result = p_sys->p_dmo->vt->ProcessInput( p_sys->p_dmo, 0, (IMediaBuffer *)p_in, DMO_INPUT_DATA_BUFFERF_TIME, i_pts * 10, 0 ); p_in->vt->Release( (IUnknown *)p_in ); if( i_result == S_FALSE ) { /* No output generated */#ifdef DMO_DEBUG msg_Dbg( p_enc, "ProcessInput(): no output generated "I64Fd, i_pts );#endif return NULL; } else if( i_result == DMO_E_NOTACCEPTING ) { /* Need to call ProcessOutput */ msg_Dbg( p_enc, "ProcessInput(): not accepting" ); } else if( i_result != S_OK ) { msg_Dbg( p_enc, "ProcessInput(): failed: %x", i_result ); return NULL; }#if DMO_DEBUG msg_Dbg( p_enc, "ProcessInput(): success" );#endif /* Get output from the DMO */ while( 1 ) { DMO_OUTPUT_DATA_BUFFER db; block_t *p_block_out; CMediaBuffer *p_out; p_block_out = block_New( p_enc, p_sys->i_min_output ); p_block_out->i_buffer = 0; p_out = CMediaBufferCreate(p_block_out, p_sys->i_min_output, VLC_FALSE); memset( &db, 0, sizeof(db) ); db.pBuffer = (IMediaBuffer *)p_out; i_result = p_sys->p_dmo->vt->ProcessOutput( p_sys->p_dmo, 0, 1, &db, &i_status ); if( i_result != S_OK ) { if( i_result != S_FALSE ) msg_Dbg( p_enc, "ProcessOutput(): failed: %x", i_result );#if DMO_DEBUG else msg_Dbg( p_enc, "ProcessOutput(): no output" );#endif p_out->vt->Release( (IUnknown *)p_out ); block_Release( p_block_out ); return p_chain; } if( !p_block_out->i_buffer ) {#if DMO_DEBUG msg_Dbg( p_enc, "ProcessOutput(): no output (i_buffer_out == 0)" );#endif p_out->vt->Release( (IUnknown *)p_out ); block_Release( p_block_out ); return p_chain; } if( db.dwStatus & DMO_OUTPUT_DATA_BUFFERF_TIME ) {#if DMO_DEBUG msg_Dbg( p_enc, "ProcessOutput(): pts: "I64Fd", "I64Fd, i_pts, db.rtTimestamp / 10 );#endif i_pts = db.rtTimestamp / 10; } if( db.dwStatus & DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH ) { p_block_out->i_length = db.rtTimelength / 10;#if DMO_DEBUG msg_Dbg( p_enc, "ProcessOutput(): length: "I64Fd, p_block_out->i_length );#endif } if( p_enc->fmt_out.i_cat == VIDEO_ES ) { if( db.dwStatus & DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT ) p_block_out->i_flags |= BLOCK_FLAG_TYPE_I; else p_block_out->i_flags |= BLOCK_FLAG_TYPE_P; } p_block_out->i_dts = p_block_out->i_pts = i_pts; block_ChainAppend( &p_chain, p_block_out ); }}/***************************************************************************** * EncoderClose: close codec *****************************************************************************/void EncoderClose( vlc_object_t *p_this ){ encoder_t *p_enc = (encoder_t*)p_this; encoder_sys_t *p_sys = p_enc->p_sys; if( !p_sys ) return; if( p_sys->p_dmo ) p_sys->p_dmo->vt->Release( (IUnknown *)p_sys->p_dmo ); FreeLibrary( p_sys->hmsdmo_dll );#ifdef LOADER#if 0 Restore_LDT_Keeper( p_sys->ldt_fs );#endif#else /* Uninitialize OLE/COM */ CoUninitialize();#endif free( p_sys );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -