Interpretation of int returned by XalanInitialize()? - xalan

I am using XALAN to transform from xsl to html,
following is the snippet of the code,
//
// XALAN_USING_XERCES(XMLPlatformUtils), init namespace
//
XALAN_USING_XALAN(XalanTransformer)
//
// 2. Initialize Xalan and Xerces
//
iRet = XalanInitialize();
how should i use this iRet to handel error cases of XalanInitialize,,,
//
// 3. Create a Xalan transformer
//
hXalan = NULL;
hXalan = CreateXalanTransformer();
if (NULL == hXalan)
{
return FALSE;
}
//
// 4. Perform transformation.
//
iRet = XalanTransformToFile(m_strPath.c_str(), strXslIn.c_str(), strHtmlOut.c_str(), hXalan);
if (0 != iRet)
{
DeleteXalanTransformer(hXalan);
XalanTerminate(false);
return FALSE;
}

Found the answer in the source code,
0 if sucessful
and -1 otherwise.
Can refer,
http://code.metager.de/source/xref/apache/xalan/c/src/xalanc/XalanTransformer/XalanCAPI.cpp#54

Related

Invalid Read of Size 4?

I'm running valgrind on a program, and while the program executes just fine, valgrind reports this:
==6542== Invalid read of size 4
==6542== at 0x8049C6F: Table::removeWebsite(Table&) (Table.cpp:146)
==6542== by 0x8049768: main (app.cpp:140)
==6542== Address 0x43f87d4 is 4 bytes inside a block of size 8 free'd
==6542== at 0x402B528: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-x86-linux.so)
==6542== by 0x8049BB0: Table::removeWebsite(Table&) (Table.cpp:124)
==6542== by 0x8049768: main (app.cpp:140)
I'm not entirely sure what is wrong. Here is the code that valgrind is pointing to...
bool Table::removeWebsite(Table& parm)
{
bool flag = false; //flag to show if an item is removed or not
int OriTableSize = currCapacity;
for (int index = 0; index < OriTableSize; index++) //search through array list, starting at index
{
Node *current = parm.aTable[index];
Node *prev = nullptr;
while (current != nullptr) //search through linked lists at array[index]
{
if (current->data->getRating() == 1) //search ratings for 1
{
if (prev == nullptr) //if current is the start of the list
{
if (current->next == nullptr) //if current is the only item in this list
{
delete current;
size--;
parm.aTable[index] = nullptr;
flag = true;
}
else
{
parm.aTable[index] = current->next; //point to the next item in list
delete current;
size--;
flag = true;
}
}
else //reset prev->next pointer to skip current
{
prev->next = current->next;
delete current;
size--;
flag = true;
}
}
prev = current;
current = current->next; //go to next position in linked list
}
}
if (flag == true)//at least one item was removed
return true;
else
return false;
}
That "delete current" points to a Node, which has:
struct Node
{
Node(const SavedWebsites& parm)
{
data = new SavedWebsites(parm);
next = nullptr;
};
~Node()
{
delete data;
next = nullptr;
}
SavedWebsites *data;
Node *next;
};
and the data in SavedWebsites has the destructor:
//Default Destructor
SavedWebsites::~SavedWebsites()
{
if (this->topic)
{
delete [] this->topic;
this->topic = nullptr;
}
if (this->website)
{
delete [] this->website;
this->website = nullptr;
}
if (this->summary)
{
delete [] this->summary;
this->summary = nullptr;
}
if (this->review)
{
delete [] this->review;
this->review = nullptr;
}
rating = 0;
}
*note the items "topic" "website" "summary" and "review" are all created with
... = new char[strlen(topic)+1] //(We have to use Cstrings)
I'm fairly new to all of this, so any ideas of what may be causing this valgrind invalid read?
You did not indicate which line corresponds to Table.cpp:146, but based on the Valgrind output, it looks like the allocation in question represents a Node instance because the size of 8 bytes matches (assuming a 32-bit system). The invalid read is triggered by the offset 4 of that instance and a size of 4, so this must correspond to the member next.
Table.cpp:146:
current = current->next; //go to next position in linked list
In case of a delete in the iteration, you access the deleted node current afterwards. You also initialize prev based on the invalid pointer, so the next pointer of the last valid node will not be updated correctly in case of deletes.
Your code seems to work fine (but is not) because its behavior depends on the allocator in use and other allocations. If the allocator were to fill the freed memory with a pattern or if that memory was reused immediately and written to, you'd see a segmentation fault.
To address this issue, I'd defer the delete. Before the next iteration, you can then either read the next node and delete the original current or update prev and read the next node.
bool del = false;
if (current->data->getRating() == 1) //search ratings for 1
{
if (prev == nullptr) //if current is the start of the list
{
if (current->next == nullptr) //if current is the only item in this list
{
parm.aTable[index] = nullptr;
}
else
{
parm.aTable[index] = current->next; //point to the next item in list
}
del = true;
flag = true;
}
else //reset prev->next pointer to skip current
{
prev->next = current->next;
del = true
flag = true;
}
}
if (del)
{
Node *deletenode = current;
current = current->next;
delete deletenode;
size--;
}
else
{
prev = current;
current = current->next; //go to next position in linked list
}

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

Record rtsp stream with ffmpeg in iOS

I've followed iFrameExtractor to successfully stream rtsp in my swift project. In this project, it also has recording function. It basically use avformat_write_header
, av_interleaved_write_frame and av_write_trailer to save the rtsp source into mp4 file.
When I used this project in my device, the rtsp streaming works fine, but recording function will always generate a blank mp4 file with no image and sound.
Could anyone tell me what step that I miss?
I'm using iPhone5 with iOS 9.1 and XCode 7.1.1.
The ffmpeg is 2.8.3 version and followed the compile instruction by CompilationGuide – FFmpeg
Following is the sample code in this project
The function that generate every frame:
-(BOOL)stepFrame {
// AVPacket packet;
int frameFinished=0;
static bool bFirstIFrame=false;
static int64_t vPTS=0, vDTS=0, vAudioPTS=0, vAudioDTS=0;
while(!frameFinished && av_read_frame(pFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// 20130525 albert.liao modified start
// Initialize a new format context for writing file
if(veVideoRecordState!=eH264RecIdle)
{
switch(veVideoRecordState)
{
case eH264RecInit:
{
if ( !pFormatCtx_Record )
{
int bFlag = 0;
//NSString *videoPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/test.mp4"];
NSString *videoPath = #"/Users/liaokuohsun/iFrameTest.mp4";
const char *file = [videoPath UTF8String];
pFormatCtx_Record = avformat_alloc_context();
bFlag = h264_file_create(file, pFormatCtx_Record, pCodecCtx, pAudioCodecCtx,/*fps*/0.0, packet.data, packet.size );
if(bFlag==true)
{
veVideoRecordState = eH264RecActive;
fprintf(stderr, "h264_file_create success\n");
}
else
{
veVideoRecordState = eH264RecIdle;
fprintf(stderr, "h264_file_create error\n");
}
}
}
//break;
case eH264RecActive:
{
if((bFirstIFrame==false) &&(packet.flags&AV_PKT_FLAG_KEY)==AV_PKT_FLAG_KEY)
{
bFirstIFrame=true;
vPTS = packet.pts ;
vDTS = packet.dts ;
#if 0
NSRunLoop *pRunLoop = [NSRunLoop currentRunLoop];
[pRunLoop addTimer:RecordingTimer forMode:NSDefaultRunLoopMode];
#else
[NSTimer scheduledTimerWithTimeInterval:5.0//2.0
target:self
selector:#selector(StopRecording:)
userInfo:nil
repeats:NO];
#endif
}
// Record audio when 1st i-Frame is obtained
if(bFirstIFrame==true)
{
if ( pFormatCtx_Record )
{
#if PTS_DTS_IS_CORRECT==1
packet.pts = packet.pts - vPTS;
packet.dts = packet.dts - vDTS;
#endif
h264_file_write_frame( pFormatCtx_Record, packet.stream_index, packet.data, packet.size, packet.dts, packet.pts);
}
else
{
NSLog(#"pFormatCtx_Record no exist");
}
}
}
break;
case eH264RecClose:
{
if ( pFormatCtx_Record )
{
h264_file_close(pFormatCtx_Record);
#if 0
// 20130607 Test
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
NSString *filePathString = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/test.mp4"];
NSURL *filePathURL = [NSURL fileURLWithPath:filePathString isDirectory:NO];
if(1)// ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:filePathURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:filePathURL completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
// TODO: error handling
NSLog(#"writeVideoAtPathToSavedPhotosAlbum error");
} else {
// TODO: success handling
NSLog(#"writeVideoAtPathToSavedPhotosAlbum success");
}
}];
}
[library release];
});
#endif
vPTS = 0;
vDTS = 0;
vAudioPTS = 0;
vAudioDTS = 0;
pFormatCtx_Record = NULL;
NSLog(#"h264_file_close() is finished");
}
else
{
NSLog(#"fc no exist");
}
bFirstIFrame = false;
veVideoRecordState = eH264RecIdle;
}
break;
default:
if ( pFormatCtx_Record )
{
h264_file_close(pFormatCtx_Record);
pFormatCtx_Record = NULL;
}
NSLog(#"[ERROR] unexpected veVideoRecordState!!");
veVideoRecordState = eH264RecIdle;
break;
}
}
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
}
else if(packet.stream_index==audioStream)
{
// 20131024 albert.liao modfied start
static int vPktCount=0;
BOOL bIsAACADTS = FALSE;
int ret = 0;
if(aPlayer.vAACType == eAAC_UNDEFINED)
{
tAACADTSHeaderInfo vxAACADTSHeaderInfo = {0};
bIsAACADTS = [AudioUtilities parseAACADTSHeader:(uint8_t *)packet.data ToHeader:&vxAACADTSHeaderInfo];
}
#synchronized(aPlayer)
{
if(aPlayer==nil)
{
aPlayer = [[AudioPlayer alloc]initAudio:nil withCodecCtx:(AVCodecContext *) pAudioCodecCtx];
NSLog(#"aPlayer initAudio");
if(bIsAACADTS)
{
aPlayer.vAACType = eAAC_ADTS;
//NSLog(#"is ADTS AAC");
}
}
else
{
if(vPktCount<5) // The voice is listened once image is rendered
{
vPktCount++;
}
else
{
if([aPlayer getStatus]!=eAudioRunning)
{
dispatch_async(dispatch_get_main_queue(), ^(void) {
#synchronized(aPlayer)
{
NSLog(#"aPlayer start play");
[aPlayer Play];
}
});
}
}
}
};
#synchronized(aPlayer)
{
int ret = 0;
ret = [aPlayer putAVPacket:&packet];
if(ret <= 0)
NSLog(#"Put Audio Packet Error!!");
}
// 20131024 albert.liao modfied end
if(bFirstIFrame==true)
{
switch(veVideoRecordState)
{
case eH264RecActive:
{
if ( pFormatCtx_Record )
{
h264_file_write_audio_frame(pFormatCtx_Record, pAudioCodecCtx, packet.stream_index, packet.data, packet.size, packet.dts, packet.pts);
}
else
{
NSLog(#"pFormatCtx_Record no exist");
}
}
}
}
}
else
{
//fprintf(stderr, "packet len=%d, Byte=%02X%02X%02X%02X%02X\n",\
packet.size, packet.data[0],packet.data[1],packet.data[2],packet.data[3], packet.data[4]);
}
// 20130525 albert.liao modified end
}
return frameFinished!=0;
}
avformat_write_header:
int h264_file_create(const char *pFilePath, AVFormatContext *fc, AVCodecContext *pCodecCtx,AVCodecContext *pAudioCodecCtx, double fps, void *p, int len )
{
int vRet=0;
AVOutputFormat *of=NULL;
AVStream *pst=NULL;
AVCodecContext *pcc=NULL, *pAudioOutputCodecContext=NULL;
avcodec_register_all();
av_register_all();
av_log_set_level(AV_LOG_VERBOSE);
if(!pFilePath)
{
fprintf(stderr, "FilePath no exist");
return -1;
}
if(!fc)
{
fprintf(stderr, "AVFormatContext no exist");
return -1;
}
fprintf(stderr, "file=%s\n",pFilePath);
// Create container
of = av_guess_format( 0, pFilePath, 0 );
fc->oformat = of;
strcpy( fc->filename, pFilePath );
// Add video stream
pst = avformat_new_stream( fc, 0 );
vVideoStreamIdx = pst->index;
fprintf(stderr,"Video Stream:%d",vVideoStreamIdx);
pcc = pst->codec;
avcodec_get_context_defaults3( pcc, AVMEDIA_TYPE_VIDEO );
// Save the stream as origin setting without convert
pcc->codec_type = pCodecCtx->codec_type;
pcc->codec_id = pCodecCtx->codec_id;
pcc->bit_rate = pCodecCtx->bit_rate;
pcc->width = pCodecCtx->width;
pcc->height = pCodecCtx->height;
if(fps==0)
{
double fps=0.0;
AVRational pTimeBase;
pTimeBase.num = pCodecCtx->time_base.num;
pTimeBase.den = pCodecCtx->time_base.den;
fps = 1.0/ av_q2d(pCodecCtx->time_base)/ FFMAX(pCodecCtx->ticks_per_frame, 1);
fprintf(stderr,"fps_method(tbc): 1/av_q2d()=%g",fps);
pcc->time_base.num = 1;
pcc->time_base.den = fps;
}
else
{
pcc->time_base.num = 1;
pcc->time_base.den = fps;
}
// reference ffmpeg\libavformat\utils.c
// For SPS and PPS in avcC container
pcc->extradata = malloc(sizeof(uint8_t)*pCodecCtx->extradata_size);
memcpy(pcc->extradata, pCodecCtx->extradata, pCodecCtx->extradata_size);
pcc->extradata_size = pCodecCtx->extradata_size;
// For Audio stream
if(pAudioCodecCtx)
{
AVCodec *pAudioCodec=NULL;
AVStream *pst2=NULL;
pAudioCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);
// Add audio stream
pst2 = avformat_new_stream( fc, pAudioCodec );
vAudioStreamIdx = pst2->index;
pAudioOutputCodecContext = pst2->codec;
avcodec_get_context_defaults3( pAudioOutputCodecContext, pAudioCodec );
fprintf(stderr,"Audio Stream:%d",vAudioStreamIdx);
fprintf(stderr,"pAudioCodecCtx->bits_per_coded_sample=%d",pAudioCodecCtx->bits_per_coded_sample);
pAudioOutputCodecContext->codec_type = AVMEDIA_TYPE_AUDIO;
pAudioOutputCodecContext->codec_id = AV_CODEC_ID_AAC;
// Copy the codec attributes
pAudioOutputCodecContext->channels = pAudioCodecCtx->channels;
pAudioOutputCodecContext->channel_layout = pAudioCodecCtx->channel_layout;
pAudioOutputCodecContext->sample_rate = pAudioCodecCtx->sample_rate;
pAudioOutputCodecContext->bit_rate = 12000;//pAudioCodecCtx->sample_rate * pAudioCodecCtx->bits_per_coded_sample;
pAudioOutputCodecContext->bits_per_coded_sample = pAudioCodecCtx->bits_per_coded_sample;
pAudioOutputCodecContext->profile = pAudioCodecCtx->profile;
//FF_PROFILE_AAC_LOW;
// pAudioCodecCtx->bit_rate;
// AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P
//pAudioOutputCodecContext->sample_fmt = AV_SAMPLE_FMT_FLTP;//pAudioCodecCtx->sample_fmt;
pAudioOutputCodecContext->sample_fmt = pAudioCodecCtx->sample_fmt;
//pAudioOutputCodecContext->sample_fmt = AV_SAMPLE_FMT_U8;
pAudioOutputCodecContext->sample_aspect_ratio = pAudioCodecCtx->sample_aspect_ratio;
pAudioOutputCodecContext->time_base.num = pAudioCodecCtx->time_base.num;
pAudioOutputCodecContext->time_base.den = pAudioCodecCtx->time_base.den;
pAudioOutputCodecContext->ticks_per_frame = pAudioCodecCtx->ticks_per_frame;
pAudioOutputCodecContext->frame_size = 1024;
fprintf(stderr,"profile:%d, sample_rate:%d, channles:%d", pAudioOutputCodecContext->profile, pAudioOutputCodecContext->sample_rate, pAudioOutputCodecContext->channels);
AVDictionary *opts = NULL;
av_dict_set(&opts, "strict", "experimental", 0);
if (avcodec_open2(pAudioOutputCodecContext, pAudioCodec, &opts) < 0) {
fprintf(stderr, "\ncould not open codec\n");
}
av_dict_free(&opts);
#if 0
// For Audio, this part is no need
if(pAudioCodecCtx->extradata_size!=0)
{
NSLog(#"extradata_size !=0");
pAudioOutputCodecContext->extradata = malloc(sizeof(uint8_t)*pAudioCodecCtx->extradata_size);
memcpy(pAudioOutputCodecContext->extradata, pAudioCodecCtx->extradata, pAudioCodecCtx->extradata_size);
pAudioOutputCodecContext->extradata_size = pAudioCodecCtx->extradata_size;
}
else
{
// For WMA test only
pAudioOutputCodecContext->extradata_size = 0;
NSLog(#"extradata_size ==0");
}
#endif
}
if(fc->oformat->flags & AVFMT_GLOBALHEADER)
{
pcc->flags |= CODEC_FLAG_GLOBAL_HEADER;
pAudioOutputCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
if ( !( fc->oformat->flags & AVFMT_NOFILE ) )
{
vRet = avio_open( &fc->pb, fc->filename, AVIO_FLAG_WRITE );
if(vRet!=0)
{
fprintf(stderr,"avio_open(%s) error", fc->filename);
}
}
// dump format in console
av_dump_format(fc, 0, pFilePath, 1);
vRet = avformat_write_header( fc, NULL );
if(vRet==0)
return 1;
else
return 0;
}
av_interleaved_write_frame:
void h264_file_write_frame(AVFormatContext *fc, int vStreamIdx, const void* p, int len, int64_t dts, int64_t pts )
{
AVStream *pst = NULL;
AVPacket pkt;
if ( 0 > vVideoStreamIdx )
return;
// may be audio or video
pst = fc->streams[ vStreamIdx ];
// Init packet
av_init_packet( &pkt );
if(vStreamIdx ==vVideoStreamIdx)
{
pkt.flags |= ( 0 >= getVopType( p, len ) ) ? AV_PKT_FLAG_KEY : 0;
//pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = pst->index;
pkt.data = (uint8_t*)p;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
// TODO: mark or unmark the log
//fprintf(stderr, "dts=%lld, pts=%lld\n",dts,pts);
// av_write_frame( fc, &pkt );
}
av_interleaved_write_frame( fc, &pkt );
}
av_write_trailer:
void h264_file_close(AVFormatContext *fc)
{
if ( !fc )
return;
av_write_trailer( fc );
if ( fc->oformat && !( fc->oformat->flags & AVFMT_NOFILE ) && fc->pb )
avio_close( fc->pb );
av_free( fc );
}
Thanks.
It looks like you're using the same AVFormatContext for both the input and output?
In the line
pst = fc->streams[ vStreamIdx ];
You're assigning the AVStream* from your AVFormatContext connected with your input (RTSP stream). But then later on you're trying to write the packet back to the same context av_interleaved_write_frame( fc, &pkt );. I kind of think of a context as a file which has helped me navagate this type of thing better. I do something identicial to what you're doing (not iOS though) where I use a separate AVFormatContext for each of the input (RTSP stream) and output (mp4 file). If I'm correct, I think what you just need to do is initialize an AVFormatContext and properly.
The following code (without error checking everything) is what I do to take an AVFormatContext * output_format_context = NULL and the AVFormatContext * input_format_context that I had associated with the RTSP stream and write from one to the other. This is after I have fetched a packet, etc., which in your case it looks like you're populating (I just take the packet from av_read_frame and re-package it.
This is code that could be in your write frame function (but it also does include the writing of the header).
AVFormatContext * output_format_context;
AVStream * in_stream_2;
AVStream * out_stream_2;
// Allocate the context with the output file
avformat_alloc_output_context2(&output_format_context, NULL, NULL, out_filename.c_str());
// Point to AVOutputFormat * output_format for manipulation
output_format = output_format_context->oformat;
// Loop through all streams
for (i = 0; i < input_format_context->nb_streams; i++) {
// Create a pointer to the input stream that was allocated earlier in the code
AVStream *in_stream = input_format_context->streams[i];
// Create a pointer to a new stream that will be part of the output
AVStream *out_stream = avformat_new_stream(output_format_context, in_stream->codec->codec);
// Set time_base of the new output stream to equal the input stream one since I'm not changing anything (can avoid but get a deprecation warning)
out_stream->time_base = in_stream->time_base;
// This is the non-deprecated way of copying all the parameters from the input stream into the output stream since everything stays the same
avcodec_parameters_from_context(out_stream->codecpar, in_stream->codec);
// I don't remember what this is for :)
out_stream->codec->codec_tag = 0;
// This just sets a flag from the format context to the stream relating to the header
if (output_format_context->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
// Check NOFILE flag and open the output file context (previously the output file was associated with the format context, now it is actually opened.
if (!(output_format->flags & AVFMT_NOFILE))
avio_open(&output_format_context->pb, out_filename.c_str(), AVIO_FLAG_WRITE);
// Write the header (not sure if this is always needed but h264 I believe it is.
avformat_write_header(output_format_context,NULL);
// Re-getting the appropriate stream that was populated above (this should allow for both audio/video)
in_stream_2 = input_format_context->streams[packet.stream_index];
out_stream_2 = output_format_context->streams[packet.stream_index];
// Rescaling pts and dts, duration and pos - you would do as you need in your code.
packet.pts = av_rescale_q_rnd(packet.pts, in_stream_2->time_base, out_stream_2->time_base, (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
packet.dts = av_rescale_q_rnd(packet.dts, in_stream_2->time_base, out_stream_2->time_base, (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
packet.duration = av_rescale_q(packet.duration, in_stream_2->time_base, out_stream_2->time_base);
packet.pos = -1;
// The first packet of my stream always gives me negative dts/pts so this just protects that first one for my purposes. You probably don't need.
if (packet.dts < 0) packet.dts = 0;
if (packet.pts < 0) packet.pts = 0;
// Finally write the frame
av_interleaved_write_frame(output_format_context, &packet);
// ....
// Write header, close/cleanup... etc
// ....
This code is fairly bare bones and doesn't include the setup (which it sounds like you're doing correctly anyway). I would also imagine this code could be cleaned up and tweaked for your purposes, but this works for me to re-write the RTSP stream into a file (in my case many files but code not shown).
The code is C code, so you might need to do minor tweaks for making it Swift compatible (for some of the library function calls maybe). I think overall it should be compatible though.
Hopefully this helps point you to the right direction. This was cobbled together thanks to several sample code sources (I don't remember where), along with warning prompts from the libraries themselves.

Comment Line Dissapears After Rewriting a Node

I was writing simple refactoring and noticed a strange thing. The comment line before the node I am rewriting disappears after refactoring. Also comments after the node in question are transferred inside the node and break the indentation in the new place. This is very strange and I want to ask if it is a bug in jdt or I did something wrong and oblivious.
For example my code suppose to refactor if-else statements in a way that the shortest branch would appear first.
when I try to refactor this:
// pre
if(a==6) {
a = 5;
return false;
} else {
a++;
}
//post
I get this:
if (!(a==6)) {
a++;
}
//post
else {
a = 5;
return false;
}
The relevant snippet where the refactoring is done:
protected ASTRewrite createRewrite(CompilationUnit cu, SubProgressMonitor pm) {
pm.beginTask("Creating rewrite operation...", 1);
final AST ast = cu.getAST();
final ASTRewrite rewrite = ASTRewrite.create(ast);
cu.accept(new ASTVisitor() {
public boolean visit(IfStatement node) {
if (node.getStartPosition() > selection.getOffset() + selection.getLength() || node.getStartPosition() < selection.getOffset())
return true;
if (node.getElseStatement() == null)
return true;
int thenCount = countNodes(node.getThenStatement());
int elseCount = countNodes(node.getElseStatement());
if(thenCount <= elseCount)
return true;
IfStatement newnode = ast.newIfStatement();
PrefixExpression neg = negateExpression(ast, rewrite, node.getExpression());
newnode.setExpression(neg);
newnode.setThenStatement((org.eclipse.jdt.core.dom.Statement) rewrite.createMoveTarget(node.getElseStatement()));
newnode.setElseStatement((org.eclipse.jdt.core.dom.Statement) rewrite.createMoveTarget(node.getThenStatement()));
rewrite.replace(node, newnode, null);
return true;
}
});
pm.done();
return rewrite;
}
The // pre comment goes away because the parser considers it to be part of the next statement (represented by node), which you replace with newNode. When node goes away, so does the attached comment.
still thinking about why the // post ends up where it does... Try replacing the newNode before setting its then and else statements

ExtJS TreeStore update event fire instead of create

I am using tree.Panel with TreeStore when I call
sel_node.parentNode.appendChild(node);
tree.getSampleStore().sync();
ExtJS fire event called sample store proxy: update url instead of create url what could I have done wrong?
What exact version of ExtJS4 do you use?
In my situation, with ext-4.0.7-gpl, I debugged a bit a found out that appendChild method creates a node from and object and then performs some update operations concerning the node's position in the tree, like setting next sibling, parent etc., see [1].
When syncing, the store uses getUpdatedRecords and getNewRecords [2] methods to determine which operation to run. update or create. Somehow, our appended children turn out to be updated, not created.
Note that the method doesn't check whether the children of a parent node was loaded, just pushes the new node into an empty childNodes array; after all these operations end, other children of a parent node are never shown in the tree; and if the update operation caused the serverside generation of new id, the code breaks on the line original = me.tree.getNodeById(record.getId()); - there is no such node with the old id generated on client side..
Simply put, I think it's a bug.
[1] http://docs.sencha.com/ext-js/4-0/source/NodeInterface.html#Ext-data-NodeInterface-method-appendChild
[2] http://docs.sencha.com/ext-js/4-0/source/AbstractStore.html#Ext-data-AbstractStore-method-getUpdatedRecords
Add: ExtJS 4.1 beta 2 doesn't work better for me
Update with temp solution: I hacked a bit and think I solved the issue by overriding the appendChild method of NodeInterface like below (just to set phantom property so that the record becomes created, not updated).
Please note:
1) You should include your appendChild call in the NodeInterface expand method callback, or the bug with pushing to the empty childNodes will remain: the new node will appear somewhere in the wrong place;
2) I had to override updateIndexes of the AbstractView as well, try not to do this and maybe you'll find out why;
3) there are some issues when the store tries to delete our newly created node the next time it syncs - couldn't trace it yet;
0) I am no way ExtJS or even JS guru, so feel free to correct this hack)
Ext.data.NodeInterface.oldGpv = Ext.data.NodeInterface.getPrototypeBody;
Ext.data.NodeInterface.getPrototypeBody = function(){
var ret = Ext.data.NodeInterface.oldGpv.apply(this, arguments);
ret.appendChild = function(node, suppressEvents, suppressNodeUpdate) {
var me = this,
i, ln,
index,
oldParent,
ps;
if (Ext.isArray(node)) {
for (i = 0, ln = node.length; i < ln; i++) {
me.appendChild(node[i]);
}
} else {
node = me.createNode(node);
if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) {
return false;
}
index = me.childNodes.length;
oldParent = node.parentNode;
if (oldParent) {
if (suppressEvents !== true && node.fireEvent("beforemove", node, oldParent, me, index) === false) {
return false;
}
oldParent.removeChild(node, null, false, true);
}else{
node.phantom = true;
}
if(me.isLoaded()){
index = me.childNodes.length;
if (index === 0) {
me.setFirstChild(node);
}
me.childNodes.push(node);
node.parentNode = me;
node.nextSibling = null;
me.setLastChild(node);
ps = me.childNodes[index - 1];
if (ps) {
node.previousSibling = ps;
ps.nextSibling = node;
ps.updateInfo(suppressNodeUpdate);
} else {
node.previousSibling = null;
}
node.updateInfo(suppressNodeUpdate);
}
//console.log('appendChild was called');
// I don't know what this code mean even given the comment
// in ExtJS native source, commented out
// As soon as we append a child to this node, we are loaded
//if (!me.isLoaded()) {
// me.set('loaded', true);
//}
// If this node didnt have any childnodes before, update myself
//else
//if (me.childNodes.length === 1) {
// me.set('loaded', me.isLoaded());
//}
if (suppressEvents !== true) {
me.fireEvent("append", me, node, index);
if (oldParent) {
node.fireEvent("move", node, oldParent, me, index);
}
}
return node;
}
};
return ret;
};
this is my code to add a node by values taken from a form domainForm. The form opens by clicking an icon in an actioncolumn of our tree grid:
var node = grid.store.getAt(rowIndex);
node.expand(false, function(){
var newDomain = domainForm.getValues();
newDomain.parent = {id: node.raw.id}; // i don't know whether you'll need this
var newNode = node.appendChild(newDomain);
me.store.sync();
});
and updateIndexes overrider:
Ext.override(Ext.view.AbstractView, {
updateIndexes : function(startIndex, endIndex) {
var ns = this.all.elements,
records = this.store.getRange(),
i;
startIndex = startIndex || 0;
endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length < records.length?(ns.length - 1):records.length-1) );
for(i = startIndex; i <= endIndex; i++){
ns[i].viewIndex = i;
ns[i].viewRecordId = records[i].internalId;
if (!ns[i].boundView) {
ns[i].boundView = this.id;
}
}
}
});
Had the same issue, an update to ext-4.1.0-beta-2 fixed it.
The reason might be wrong format of data that comes from the server in response to your request.
Syncronization doesn't happen. Pass 'success' key with the value of TRUE in the server response.
Hmm ... try this ...
beforeitemexpand(node, eOpts){
if (node.data.expanded) return false
}