This question is regarding Rasdial and pbk file.
I am updating the pbk file using "rassetentryproperties" and dialling through "rasdialdlg".
The below flags decide the parameters of the pbk file inturn responisble for the property of the dial-up connection.
I am presetting the flags as:
RasEntry.dwfOptions = 0x00000000;
RasEntry.dwfOptions2 = 0x00000000;
Trying to do as below to set Flag1 and Flag2.
RasEntry.dwfOptions |= (Set Flag1 | Set Flag2)
However, my pbk file entries are not actually setting, as i set above.
Also, for the same code, Win7 pbk and win xp pbk are different.
Where i am wrong?
Code Sample for the reference:
BOOL Create_Phone_Book ( LPTSTR DeviceName ) {
DWORD regError;
TCHAR DeviceName[100];
if ( _tcscpy ( DeviceName, DeviceName ) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS );
} else {
Slog ( TEXT ("Strcpy Failed To copy deviceName to DeviceName"), NOLASTERROR);
return FALSE;
}
RASENTRY RasEntry;
DWORD cb;
RASDIALPARAMS RasDialParams;
memset((LPTSTR)&RasEntry, 0, sizeof(RASENTRY));
RasEntry.dwSize = sizeof(RASENTRY);
cb = sizeof(RASENTRY);
regError = RasGetEntryProperties (NULL, TEXT (""), &RasEntry, &cb, NULL, NULL);
if ( regError == ERROR_SUCCESS ) {
Slog ( TEXT ("RasGetEntryProperties Success"), APISUCCESS );
} else {
RAS_ErrorHandler ( regError );
return FALSE;
}
RasEntry.dwfOptions = 0x00000000;
RasEntry.dwfOptions2 = 0x00000000;
RasEntry.dwfOptions |= ( RASEO_IpHeaderCompression | RASEO_ModemLights |RASEO_SwCompression |
RASEO_ShowDialingProgress | RASEO_NetworkLogon | RASEO_DisableLcpExtensions );
RasEntry.dwfOptions2 |= ( RASEO2_UseGlobalDeviceSettings | RASEO2_Internet );
if ( _tcscpy ( RasEntry.szDeviceType, RASDT_Modem ) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS );
} else {
Slog ( TEXT ("Strcpy Failed copy RASDT_MODEM to RasEntry.szDeviceType"), NOLASTERROR);
return FALSE;
}
if ( _tcscpy ( RasEntry.szDeviceName, DeviceName ) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS );
} else {
Slog ( TEXT ("Strcpy Failed copy DeviceName to RasEntry.szDeviceName"), NOLASTERROR);
return FALSE;
}
regError = RasSetEntryProperties( NULL , Dial_Up_Name, &RasEntry, sizeof(RasEntry),NULL, 0);
if ( regError == ERROR_SUCCESS ) {
Slog ( TEXT ("RasSetEntryProperties Succeeded"), APISUCCESS);
} else {
RAS_ErrorHandler ( regError );
return FALSE;
}
memset((LPTSTR)&RasDialParams, 0, sizeof(RasDialParams));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
if ( _tcscpy (RasDialParams.szEntryName, Dial_Up_Name ) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS);
} else {
Slog ( TEXT ("Strcpy Failed Copy Dial_Up_Name to RasDialParams.szEntryName"), NOLASTERROR);
return FALSE;
}
if ( _tcscpy (RasDialParams.szUserName, TEXT ("")) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS);
} else {
Slog ( TEXT ("Strcpy Failed Copy "" to RasDialParams.szUserName"), NOLASTERROR);
return FALSE;
}
if ( _tcscpy (RasDialParams.szPassword, TEXT ("")) != NULL ) {
Slog ( TEXT ("Strcpy Success"), APISUCCESS);
} else {
Slog ( TEXT ("Strcpy Failed Copy "" to RasDialParams.szPassword"), NOLASTERROR);
return FALSE;
}
regError = RasSetEntryDialParams ( NULL, &RasDialParams, FALSE);
if ( regError == ERROR_SUCCESS ) {
Slog ( TEXT ("RasSetEntryDialParams Success"), APISUCCESS );
} else {
RAS_ErrorHandler ( regError );
return FALSE;
}
return TRUE;
}
Updated 1:
Typically, i need to create an Dial-Up connection as i like. Please look at the screen shot attached.
As seen in the snap, i have to set and reset many parameters(Set-Display Progress while connecting, Reset- Prompt for UN and PW).
These two flags use to set and reset whatever we want by "or"ing
RasEntry.dwfOptions
RasEntry.dwfOptions2
So what i do in my code is :
resetting the flag:
RasEntry.dwfOptions = 0x00000000;
RasEntry.dwfOptions2 = 0x00000000;
and to set:
RasEntry.dwfOptions |= ( RASEO_IpHeaderCompression | RASEO_ModemLights
|RASEO_SwCompression | RASEO_ShowDialingProgress |
RASEO_NetworkLogon | RASEO_DisableLcpExtensions );
So, the remaining flags other than the above, will be remained Unset.
Now the problem is, Whatever i am setting in the above steps are not actually setting in the dial-up connection. In another way, some parameters are not set even, if i set in the code.
What should i do to get rid of my problem?
Related
The following code creates a window with a opengl rendering context.
Everything works fine, but somehow the window close event doesn't correlate to the wm_delete_window atom.
static int
hnd_connect_to_xcb
(
hnd_linux_window_t *_window
)
{
_window->renderer.display = XOpenDisplay((char *)NULL);
if (!hnd_assert(_window->renderer.display != NULL, "Could not open display"))
return HND_NK;
_window->renderer.default_screen = DefaultScreen(_window->renderer.display);
_window->connection = XGetXCBConnection(_window->renderer.display);
if (!hnd_assert(_window->connection != NULL, "Could not connect to X display"))
return HND_NK;
XSetEventQueueOwner(_window->renderer.display, XCBOwnsEventQueue);
/* Get screen data */
xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(_window->connection));
for (int i = _window->renderer.default_screen; i > 0; --i)
xcb_screen_next(&screen_iterator);
_window->screen_data = screen_iterator.data;
if (!hnd_set_fb_configs(&_window->renderer))
return HND_NK;
return HND_OK;
}
static void
hnd_set_window_properties
(
hnd_linux_window_t *_window
)
{
/* Set title */
xcb_intern_atom_cookie_t utf8_string_cookie =
hnd_create_intern_atom_cookie(_window->connection, HND_NK, "UTF8_STRING");
_window->utf8_string = hnd_create_intern_atom_reply(_window->connection, utf8_string_cookie);
xcb_intern_atom_cookie_t wm_name_cookie =
hnd_create_intern_atom_cookie(_window->connection, HND_NK, "WM_NAME");
_window->wm_name = hnd_create_intern_atom_reply(_window->connection, wm_name_cookie);
xcb_change_property(_window->connection,
XCB_PROP_MODE_REPLACE,
_window->id,
_window->wm_name->atom,
_window->utf8_string->atom,
8,
strlen(_window->title),
_window->title);
/* Add listener for close event */
xcb_intern_atom_cookie_t wm_protocols_cookie =
hnd_create_intern_atom_cookie(_window->connection, HND_OK, "WM_PROTOCOLS");
_window->wm_protocols = hnd_create_intern_atom_reply(_window->connection, wm_protocols_cookie);
xcb_intern_atom_cookie_t wm_delete_cookie =
hnd_create_intern_atom_cookie(_window->connection, HND_NK, "WM_DELETE_WINDOW");
_window->wm_delete_window = hnd_create_intern_atom_reply(_window->connection, wm_delete_cookie);
xcb_change_property(_window->connection,
XCB_PROP_MODE_REPLACE,
_window->id,
_window->wm_protocols->atom,
XCB_ATOM_ATOM,
32,
1,
&_window->wm_delete_window->atom);
}
hnd_linux_window_t *
hnd_create_window
(
const char *_title,
unsigned int _left,
unsigned int _top,
unsigned int _width,
unsigned int _height,
unsigned int _decoration
)
{
hnd_linux_window_t *new_window = malloc(sizeof(hnd_linux_window_t));
if (!hnd_assert(new_window != NULL, NULL))
return NULL;
if (!hnd_connect_to_xcb(new_window))
return NULL;
new_window->title = (char *)_title;
new_window->left = _left;
new_window->top = _top;
new_window->width = _width;
new_window->height = _height;
new_window->running = HND_OK;
if (!hnd_init_renderer(&new_window->renderer))
{
hnd_destroy_window(new_window);
return NULL;
}
new_window->colormap_id = xcb_generate_id(new_window->connection);
xcb_create_colormap(new_window->connection,
XCB_COLORMAP_ALLOC_NONE,
new_window->colormap_id,
new_window->screen_data->root,
new_window->renderer.visual_id);
new_window->value_mask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
new_window->event_mask = XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_POINTER_MOTION |
XCB_EVENT_MASK_BUTTON_MOTION |
XCB_EVENT_MASK_ENTER_WINDOW |
XCB_EVENT_MASK_LEAVE_WINDOW |
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE;
new_window->value_list[0] = new_window->event_mask;
new_window->value_list[1] = new_window->colormap_id;
/* Create window */
new_window->id = xcb_generate_id(new_window->connection);
xcb_create_window(new_window->connection,
XCB_COPY_FROM_PARENT,
new_window->id,
new_window->screen_data->root,
new_window->left,
new_window->top,
new_window->width,
new_window->height,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
new_window->renderer.visual_id,
new_window->value_mask,
new_window->value_list);
hnd_set_window_properties(new_window);
hnd_set_window_decoration(new_window, _decoration);
xcb_map_window(new_window->connection, new_window->id);
xcb_flush(new_window->connection);
/* Finish opengl binding */
new_window->renderer.gl_window = glXCreateWindow(new_window->renderer.display,
new_window->renderer.current_fb_config,
new_window->id,
0);
if (!hnd_assert(new_window->renderer.gl_window, "Could not create OpenGL window"))
{
hnd_destroy_window(new_window);
return NULL;
}
if (!hnd_assert(glXMakeContextCurrent(new_window->renderer.display,
new_window->renderer.gl_window,
new_window->renderer.gl_window,
new_window->renderer.gl_context),
"Could not set OpenGL current rendering context"))
{
hnd_destroy_window(new_window);
return NULL;
}
hnd_print_debug(HND_LOG, HND_CREATED("OpenGL context"), HND_SUCCESS);
hnd_print_debug(HND_LOG, HND_CREATED("window"), HND_SUCCESS);
return new_window;
}
void
hnd_destroy_window
(
hnd_linux_window_t *_window
)
{
if (!hnd_assert(_window != NULL, HND_SYNTAX))
return;
hnd_end_renderer(&_window->renderer);
xcb_free_colormap(_window->connection, _window->colormap_id);
hnd_print_debug(HND_LOG, HND_ENDED("window"), HND_SUCCESS);
}
void
hnd_poll_events
(
hnd_linux_window_t *_window,
hnd_event_t *_event
)
{
if (!hnd_assert(_window != NULL, HND_SYNTAX))
return;
if (!hnd_assert(_event != NULL, HND_SYNTAX))
return;
_event->xcb_event = xcb_poll_for_event(_window->connection);
if (!_event->xcb_event)
return;
switch (_event->xcb_event->response_type & 0x7f)
{
case XCB_EXPOSE:
xcb_flush(_window->connection);
break;
case XCB_KEY_PRESS:
hnd_queue_key_event(_event->pressed_keys, _event->xcb_event);
break;
case XCB_KEY_RELEASE:
hnd_queue_key_event(_event->released_keys, _event->xcb_event);
break;
case XCB_CLIENT_MESSAGE:
{
xcb_client_message_event_t *temp_client_message_event = (xcb_client_message_event_t *)_event;
if (temp_client_message_event->data.data32[0] == _window->wm_delete_window->atom)
_window->running = HND_NK;
} break;
default:
break;
}
}
Most of the renderer functions won't help much, besides these two helpers that create the atoms:
xcb_intern_atom_cookie_t
hnd_create_intern_atom_cookie
(
xcb_connection_t *_connection,
unsigned int _exists,
const char *_string
)
{
return xcb_intern_atom(_connection, _exists, strlen(_string), _string);
}
xcb_intern_atom_reply_t *
hnd_create_intern_atom_reply
(
xcb_connection_t *_connection,
xcb_intern_atom_cookie_t _cookie
)
{
xcb_intern_atom_reply_t *new_atom_reply = xcb_intern_atom_reply(_connection, _cookie, NULL);
if (!hnd_assert(new_atom_reply != NULL, "Could not create atom"))
return NULL;
return new_atom_reply;
}
And yes, I'm including external files. Everything compiles correctly.
The problem is basically a typo:
_event->xcb_event = xcb_poll_for_event(_window->connection);
[...]
switch (_event->xcb_event->response_type & 0x7f)
{
[...]
case XCB_CLIENT_MESSAGE:
{
xcb_client_message_event_t *temp_client_message_event = (xcb_client_message_event_t *)_event;
You are saving the event in _event->xcb_event. But you are casting _event to xcb_client_message_event_t*. You should be casting _event->xcb_event.
So, that last line should be:
xcb_client_message_event_t *temp_client_message_event = (xcb_client_message_event_t *)_event->xcb_event;
I'm writing program on C to capture RTSP stream and write it to files.
But after some time i get errors:
Too large number of skipped frames xxxx > 60000
After this files become incorrect and very small size.
What the reason of it and how can o fix this problems?
a piece of code, where i capture frames and put them to buffer.
ofmt = av_guess_format( NULL, sFileOutput, NULL );
ofcx = avformat_alloc_context();
ofcx->oformat = ofmt;
int ret2=avio_open( &ofcx->pb, sFileOutput, AVIO_FLAG_WRITE);
if(ret2<0){
fprintf(stderr, "\nError occurred when opening output file: %s\n",av_err2str(ret2));
}
ost = avformat_new_stream( ofcx, NULL );
avcodec_copy_context( ost->codec, iccx );
ost->sample_aspect_ratio.num = iccx->sample_aspect_ratio.num;
ost->sample_aspect_ratio.den = iccx->sample_aspect_ratio.den;
ost->r_frame_rate = ist->r_frame_rate;
ost->avg_frame_rate = ost->r_frame_rate;
ost->time_base = av_inv_q( ost->r_frame_rate );
ost->codec->time_base = ost->time_base;
ost->codec->width = 1280;
ost->codec->height = 800;
av_init_packet( &pkt );
while ( av_read_frame( ifcx, &pkt ) >= 0 && start_flag==0 && stop_flag==0){
if ( pkt.stream_index == i_index ) {
pkt.stream_index = ost->id;
pkt.pts = av_rescale_q_rnd(pkt.pts, ist->time_base, ost->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, ist->time_base, ost->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
pkt.pos = -1;
av_copy_packet(&pkt_arr[pkg_index],&pkt);
}
av_free_packet( &pkt );
av_init_packet( &pkt );
pkg_index++;
if(pkg_index>=bufer_size){
pkg_index=pkg_index-bufer_size;
}
}
I have a problem with a combo box, I can't display the data inside the combo, I have to do right click before a left click to show my data, but with a just a left click its not possible.
The below image show the first case(when I do a left click)
.
The below image show the second case(when I do a right click before the left click)
Thanks for help
/**
* Configure the renderer appropriately with the status of the
* Drawing object.
*/
public Component getListCellRendererComponent( JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus ) {
Component theResult = super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
System.out.println("theResult : "+theResult.toString());
System.out.println("déb methode getLi class AWICombo => value "+value+" ,index "+index+" ,isSelected "+isSelected+",celhasFocus "+cellHasFocus);
// display crash in combo box with jdk 1.3 : setOpaque(true) solves the problem.
//( (JComponent) theResult ).setOpaque( true );
//setOpaque( true );
if ( index == -1 ) {
System.out.println("In if index == -1");
return theResult;
}
try {
System.out.println("In try bloc 1");
boolean notEmpty = false;
AWCState theObjectToDisplay = null;
try {
System.out.println("In try bloc 2");
System.out.println("index " +index);
System.out.println("theModel call :" +theModel.toString());
theObjectToDisplay = (AWCState) theModel.theComboValues.elementAt( index );
System.out.println("theObjectToDisplay => "+theObjectToDisplay.toString());
System.out.println("dans conbobox "+index);
} catch ( java.lang.ArrayIndexOutOfBoundsException aioobe ) {
aioobe.printStackTrace();
}
// test if the first square of the conbo box is empty for doen't set the tool tips
if ( theObjectToDisplay != null ) {
System.out.println("In if 1");
if ( theObjectToDisplay.toString() != null ) {
System.out.println("In if 2");
if ( value.toString().compareTo( theObjectToDisplay.toString() ) != 0 ) {
System.out.println("In if 3");
if ( value.toString().compareTo( "" ) != 0 ) {
System.out.println("In if 4");
theObjectToDisplay = (AWCState) theModel.theComboValues.elementAt( index - 1 );
notEmpty = true;
}
} else {
System.out.println("In else 1");
notEmpty = true;
}
}
} else {
System.out.println("In else 2");
theObjectToDisplay = (AWCState) theModel.theComboValues.elementAt( index - 1 );
notEmpty = true;
}
if ( isSelected ) {
System.out.println("In if isSelected "+list.getSelectionBackground());
System.out.println("In if isSelected "+list.getSelectionForeground());
setBackground( list.getSelectionBackground() );
setForeground( list.getSelectionForeground() );
setToolTip( list, notEmpty, theObjectToDisplay, value );
} else {
setBackground( list.getBackground() );
setForeground( list.getForeground() );
}
setFont( list.getFont() );
if ( value == null ) {
System.out.println("In if value == null");
setText("");
}
else {
setText(value.toString());
}
// object is not obsolete
if ( theObjectToDisplay == null || theObjectToDisplay.getStatus().equals( AWCConstants.OFFICIAL ) ) {
System.out.println("object is not obsolete theObjectToDisplay=>"+theObjectToDisplay.toString());
return theResult;
}
// object is obsolete
if ( index == 1 ) {
return theResult;
}
if ( !isSelected ) {
theResult.setBackground( Color.red );
} else {
theResult.setBackground( new Color( 155, 100, 155 ) );
}
}
catch ( NullPointerException npe ) {
npe.printStackTrace();
}
catch ( java.lang.ArrayIndexOutOfBoundsException aioobe ) {
aioobe.printStackTrace();
}
System.out.println("end of function");
return theResult;
}
I read h.264 frames from webcamera and capture audio from microphone. I need to stream live video to ffserver. During debug I read video from ffserver using ffmpeg with following command:
ffmpeg -i http://127.0.0.1:12345/robot.avi -vcodec copy -acodec copy out.avi
My video in output file is slightly accelerated. If I add a audio stream it is accelerated several times. Sometimes there is no audio in the output file.
Here is my code for encoding audio:
#include "v_audio_encoder.h"
extern "C" {
#include <libavcodec/avcodec.h>
}
#include <cassert>
struct VAudioEncoder::Private
{
AVCodec *m_codec;
AVCodecContext *m_context;
std::vector<uint8_t> m_outBuffer;
};
VAudioEncoder::VAudioEncoder( int sampleRate, int bitRate )
{
d = new Private( );
d->m_codec = avcodec_find_encoder( CODEC_ID_MP3 );
assert( d->m_codec );
d->m_context = avcodec_alloc_context3( d->m_codec );
// put sample parameters
d->m_context->channels = 2;
d->m_context->bit_rate = bitRate;
d->m_context->sample_rate = sampleRate;
d->m_context->sample_fmt = AV_SAMPLE_FMT_S16;
strcpy( d->m_context->codec_name, "libmp3lame" );
// open it
int res = avcodec_open2( d->m_context, d->m_codec, 0 );
assert( res >= 0 );
d->m_outBuffer.resize( d->m_context->frame_size );
}
VAudioEncoder::~VAudioEncoder( )
{
avcodec_close( d->m_context );
av_free( d->m_context );
delete d;
}
void VAudioEncoder::encode( const std::vector<uint32_t>& samples, std::vector<uint8_t>& outbuf )
{
assert( (int)samples.size( ) == d->m_context->frame_size );
int outSize = avcodec_encode_audio( d->m_context, d->m_outBuffer.data( ),
d->m_outBuffer.size( ), reinterpret_cast<const short*>( samples.data( ) ) );
if( outSize ) {
outbuf.resize( outSize );
memcpy( outbuf.data( ), d->m_outBuffer.data( ), outSize );
}
else
outbuf.clear( );
}
int VAudioEncoder::getFrameSize( ) const
{
return d->m_context->frame_size;
}
Here is my code for streaming video:
#include "v_out_video_stream.h"
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/avstring.h>
#include <libavformat/avio.h>
}
#include <stdexcept>
#include <cassert>
struct VStatticRegistrar
{
VStatticRegistrar( )
{
av_register_all( );
avformat_network_init( );
}
};
VStatticRegistrar __registrar;
struct VOutVideoStream::Private
{
AVFormatContext * m_context;
int m_videoStreamIndex;
int m_audioStreamIndex;
int m_videoBitrate;
int m_width;
int m_height;
int m_fps;
int m_bitrate;
bool m_waitKeyFrame;
};
VOutVideoStream::VOutVideoStream( int width, int height, int fps, int bitrate )
{
d = new Private( );
d->m_width = width;
d->m_height = height;
d->m_fps = fps;
d->m_context = 0;
d->m_videoStreamIndex = -1;
d->m_audioStreamIndex = -1;
d->m_bitrate = bitrate;
d->m_waitKeyFrame = true;
}
bool VOutVideoStream::connectToServer( const std::string& uri )
{
assert( ! d->m_context );
// initalize the AV context
d->m_context = avformat_alloc_context();
if( !d->m_context )
return false;
// get the output format
d->m_context->oformat = av_guess_format( "ffm", NULL, NULL );
if( ! d->m_context->oformat )
return false;
strcpy( d->m_context->filename, uri.c_str( ) );
// add an H.264 stream
AVStream *stream = avformat_new_stream( d->m_context, NULL );
if ( ! stream )
return false;
// initalize codec
AVCodecContext* codec = stream->codec;
if( d->m_context->oformat->flags & AVFMT_GLOBALHEADER )
codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
codec->codec_id = CODEC_ID_H264;
codec->codec_type = AVMEDIA_TYPE_VIDEO;
strcpy( codec->codec_name, "libx264" );
// codec->codec_tag = ( unsigned('4') << 24 ) + (unsigned('6') << 16 ) + ( unsigned('2') << 8 ) + 'H';
codec->width = d->m_width;
codec->height = d->m_height;
codec->time_base.den = d->m_fps;
codec->time_base.num = 1;
codec->bit_rate = d->m_bitrate;
d->m_videoStreamIndex = stream->index;
// add an MP3 stream
stream = avformat_new_stream( d->m_context, NULL );
if ( ! stream )
return false;
// initalize codec
codec = stream->codec;
if( d->m_context->oformat->flags & AVFMT_GLOBALHEADER )
codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
codec->codec_id = CODEC_ID_MP3;
codec->codec_type = AVMEDIA_TYPE_AUDIO;
strcpy( codec->codec_name, "libmp3lame" );
codec->sample_fmt = AV_SAMPLE_FMT_S16;
codec->channels = 2;
codec->bit_rate = 64000;
codec->sample_rate = 44100;
d->m_audioStreamIndex = stream->index;
// try to open the stream
if( avio_open( &d->m_context->pb, d->m_context->filename, AVIO_FLAG_WRITE ) < 0 )
return false;
// write the header
return avformat_write_header( d->m_context, NULL ) == 0;
}
void VOutVideoStream::disconnect( )
{
assert( d->m_context );
avio_close( d->m_context->pb );
avformat_free_context( d->m_context );
d->m_context = 0;
}
VOutVideoStream::~VOutVideoStream( )
{
if( d->m_context )
disconnect( );
delete d;
}
int VOutVideoStream::getVopType( const std::vector<uint8_t>& image )
{
if( image.size( ) < 6 )
return -1;
unsigned char *b = (unsigned char*)image.data( );
// Verify NAL marker
if( b[ 0 ] || b[ 1 ] || 0x01 != b[ 2 ] ) {
++b;
if ( b[ 0 ] || b[ 1 ] || 0x01 != b[ 2 ] )
return -1;
}
b += 3;
// Verify VOP id
if( 0xb6 == *b ) {
++b;
return ( *b & 0xc0 ) >> 6;
}
switch( *b ) {
case 0x65: return 0;
case 0x61: return 1;
case 0x01: return 2;
}
return -1;
}
bool VOutVideoStream::sendVideoFrame( std::vector<uint8_t>& image )
{
// Init packet
AVPacket pkt;
av_init_packet( &pkt );
pkt.flags |= ( 0 >= getVopType( image ) ) ? AV_PKT_FLAG_KEY : 0;
// Wait for key frame
if ( d->m_waitKeyFrame ) {
if( pkt.flags & AV_PKT_FLAG_KEY )
d->m_waitKeyFrame = false;
else
return true;
}
pkt.stream_index = d->m_videoStreamIndex;
pkt.data = image.data( );
pkt.size = image.size( );
pkt.pts = pkt.dts = AV_NOPTS_VALUE;
return av_write_frame( d->m_context, &pkt ) >= 0;
}
bool VOutVideoStream::sendAudioFrame( std::vector<uint8_t>& audio )
{
// Init packet
AVPacket pkt;
av_init_packet( &pkt );
pkt.stream_index = d->m_audioStreamIndex;
pkt.data = audio.data( );
pkt.size = audio.size( );
pkt.pts = pkt.dts = AV_NOPTS_VALUE;
return av_write_frame( d->m_context, &pkt ) >= 0;
}
Here is how I use it:
BOOST_AUTO_TEST_CASE(testSendingVideo)
{
const int framesToGrab = 90000;
VOutVideoStream stream( VIDEO_WIDTH, VIDEO_HEIGHT, FPS, VIDEO_BITRATE );
if( stream.connectToServer( URI ) ) {
VAudioEncoder audioEncoder( AUDIO_SAMPLE_RATE, AUDIO_BIT_RATE );
VAudioCapture microphone( MICROPHONE_NAME, AUDIO_SAMPLE_RATE, audioEncoder.getFrameSize( ) );
VLogitecCamera camera( VIDEO_WIDTH, VIDEO_HEIGHT );
BOOST_REQUIRE( camera.open( CAMERA_PORT ) );
BOOST_REQUIRE( camera.startCapturing( ) );
std::vector<uint8_t> image, encodedAudio;
std::vector<uint32_t> voice;
boost::system_time startTime;
int delta;
for( int i = 0; i < framesToGrab; ++i ) {
startTime = boost::posix_time::microsec_clock::universal_time( );
BOOST_REQUIRE( camera.read( image ) );
BOOST_REQUIRE( microphone.read( voice ) );
audioEncoder.encode( voice, encodedAudio );
BOOST_REQUIRE( stream.sendVideoFrame( image ) );
BOOST_REQUIRE( stream.sendAudioFrame( encodedAudio ) );
delta = ( boost::posix_time::microsec_clock::universal_time( ) - startTime ).total_milliseconds( );
if( delta < 1000 / FPS )
boost::thread::sleep( startTime + boost::posix_time::milliseconds( 1000 / FPS - delta ) );
}
BOOST_REQUIRE( camera.stopCapturing( ) );
BOOST_REQUIRE( camera.close( ) );
}
else
std::cout << "failed to connect to server" << std::endl;
}
I think my problem is in PTS and DTS. Can anyone help me?
It is problem of using AutoSize for label which are drawn by Tahoma font with option TextRenderingHint.ClearTypeGridFit.
Without ClearTypeGridFit it looks ok, but with - it cropped by parent container (see attached image: on first label ',' is cropped)
I've found it is only with Tahoma font.
Code of customlabel:
class CustomLabel: Label
{
public CustomLabel ()
:base()
{
}
protected override void OnPaint ( PaintEventArgs e )
{
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
base.OnPaint( e );
}
}
Peace of code from designer file:
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font( "Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ( (byte)( 0 ) ) );
this.label1.Location = new System.Drawing.Point( 54, 95 );
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size( 35, 13 );
this.label1.TabIndex = 1;
this.label1.Text = resources.GetString( "label1.Text" );
//
// customLabel1
//
this.customLabel1.AutoSize = true;
this.customLabel1.BackColor = System.Drawing.Color.NavajoWhite;
this.customLabel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.customLabel1.Font = new System.Drawing.Font( "Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ( (byte)( 0 ) ) );
this.customLabel1.ForeColor = System.Drawing.Color.Black;
this.customLabel1.Location = new System.Drawing.Point( 1, 1 );
this.customLabel1.Margin = new System.Windows.Forms.Padding( 0 );
this.customLabel1.Name = "customLabel1";
this.customLabel1.Size = new System.Drawing.Size( 192, 154 );
this.customLabel1.TabIndex = 0;
this.customLabel1.Text = resources.GetString( "customLabel1.Text" );
What I have found just a overridden a GetPreferedSize function:
public override Size GetPreferredSize ( Size theProposedSize )
{
if ( TextRendering == TextRenderingHint.ClearTypeGridFit )
{
Graphics aGraphics = Graphics.FromHwnd( this.Handle );
if ( aGraphics != null )
{
aGraphics.TextRenderingHint = theTextRendering;
Size aResult = TextRenderer.MeasureText( aGraphics, Text, Font, theProposedSize );
//apply control minimum size
aResult.Height = Math.Max( aResult.Height, MinimumSize.Height );
aResult.Width = Math.Max( aResult.Width, MinimumSize.Width );
return aResult;
}
}
return base.GetPreferredSize( theProposedSize );
}
But I can't apply a Maximum size to the result.
Why I need a Maximum size? For example, I want to have a possibility to limit labels by width.
Any ideas?
So, my final solution looks so:
public override Size GetPreferredSize ( Size theProposedSize )
{
if ( SystemInfo.WinVersion == SystemInfo.Version.WindowsXP )
{
if ( theTextRendering == TextRenderingHint.ClearTypeGridFit )
{
Graphics aGraphics = Graphics.FromHwnd( this.Handle );
if ( aGraphics != null )
{
aGraphics.TextRenderingHint = theTextRendering;
Size aResult = TextRenderer.MeasureText( aGraphics, Text, Font, theProposedSize );
//apply padding and margin
aResult.Width += Margin.Horizontal + Padding.Horizontal;
aResult.Height += Margin.Vertical + Padding.Vertical;
//apply control minimum size
aResult.Height = Math.Max( aResult.Height, MinimumSize.Height );
aResult.Width = Math.Max( aResult.Width, MinimumSize.Width );
//adopt maximum width
if ( MaximumSize.Width > 0 )
{
while ( aResult.Width > MaximumSize.Width )
{
aResult.Width -= MaximumSize.Width;
aResult.Height += Font.Height;
if ( aResult.Width < MaximumSize.Width )
{
aResult.Width = MaximumSize.Width;
}
}
}
return aResult;
}
}
}
return base.GetPreferredSize( theProposedSize );
}