Exemple #1
0
/*
 * Support functions for write_unblocked.
 * They originate from Ruby's io.c. We redefine them here 
 * because in that file they are declared with static, so
 * they aren't accessible here.
 */
static int io_fflush(rb_io_t *fptr){
    rb_io_check_closed(fptr);
    if (fptr->wbuf_len == 0)
        return 0;
    if (!rb_thread_fd_writable(fptr->fd)) {
        rb_io_check_closed(fptr);
    }
    while (fptr->wbuf_len > 0 && io_flush_buffer(fptr) != 0) {
	if (!rb_io_wait_writable(fptr->fd))
	    return -1;
        rb_io_check_closed(fptr);
    }
    return 0;
}
Exemple #2
0
static int avi_write_ix(avi_Context* AVI)
{
    char tag[5];
    char ix_tag[] = "ix00";
    int i, j;

	avi_RIFF *riff = avi_get_last_riff(AVI);

    if (riff->id > AVI_MASTER_INDEX_SIZE)
        return -1;

    for (i=0;i<AVI->stream_list_size;i++)
    {
        io_Stream *stream = get_stream(AVI->stream_list, i);
        int64_t ix, pos;

        avi_stream2fourcc(tag, stream);

        ix_tag[3] = '0' + i; /*only 10 streams supported*/

        /* Writing AVI OpenDML leaf index chunk */
        ix = io_get_offset(AVI->writer);
        io_write_4cc(AVI->writer, ix_tag);     /* ix?? */
        avi_Index* indexes = (avi_Index *) stream->indexes;
        io_write_wl32(AVI->writer, indexes->entry * 8 + 24);
                                      /* chunk size */
        io_write_wl16(AVI->writer, 2);           /* wLongsPerEntry */
        io_write_w8(AVI->writer, 0);             /* bIndexSubType (0 == frame index) */
        io_write_w8(AVI->writer, AVI_INDEX_OF_CHUNKS); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */
        io_write_wl32(AVI->writer, indexes->entry);
                                      /* nEntriesInUse */
        io_write_4cc(AVI->writer, tag);        /* dwChunkId */
        io_write_wl64(AVI->writer, riff->movi_list);/* qwBaseOffset */
        io_write_wl32(AVI->writer, 0);             /* dwReserved_3 (must be 0) */

        for (j=0; j< indexes->entry; j++)
        {
             avi_Ientry* ie = avi_get_ientry(indexes, j);
             io_write_wl32(AVI->writer, ie->pos + 8);
             io_write_wl32(AVI->writer, ((uint32_t)ie->len & ~0x80000000) |
                          (ie->flags & 0x10 ? 0 : 0x80000000));
         }
         io_flush_buffer(AVI->writer);
         pos = io_get_offset(AVI->writer); //current position
         fprintf(stderr,"AVI: wrote ix %s with %i entries\n",tag, indexes->entry);

         /* Updating one entry in the AVI OpenDML master index */
         io_seek(AVI->writer, indexes->indx_start);
         io_write_4cc(AVI->writer, "indx");            /* enabling this entry */
         io_skip(AVI->writer, 8);
         io_write_wl32(AVI->writer, riff->id);         /* nEntriesInUse */
         io_skip(AVI->writer, 16*(riff->id));
         io_write_wl64(AVI->writer, ix);               /* qwOffset */
         io_write_wl32(AVI->writer, pos - ix);         /* dwSize */
         io_write_wl32(AVI->writer, indexes->entry);   /* dwDuration */
		
		//return to position
         io_seek(AVI->writer, pos);
    }
    return 0;
}
Exemple #3
0
int avi_write_packet(avi_Context* AVI, int stream_index, BYTE *data, uint32_t size, int64_t dts, int block_align, int32_t flags)
{
    char tag[5];
    unsigned int i_flags=0;

    io_Stream *stream= get_stream(AVI->stream_list, stream_index);

	avi_RIFF* riff = avi_get_last_riff(AVI);
	//align
    while(block_align==0 && dts != AV_NOPTS_VALUE && dts > stream->packet_count)
        avi_write_packet(AVI, stream_index, NULL, 0, AV_NOPTS_VALUE, 0, 0);

    stream->packet_count++;

    // Make sure to put an OpenDML chunk when the file size exceeds the limits
    if (io_get_offset(AVI->writer) - riff->riff_start > AVI_MAX_RIFF_SIZE)
    {
        avi_write_ix(AVI);
        avi_close_tag(AVI, riff->movi_list);

        if (riff->id == 1)
            avi_write_idx1(AVI, riff);

        avi_close_tag(AVI, riff->riff_start);

        avi_add_new_riff(AVI);
        
        riff = avi_get_last_riff(AVI); //update riff
    }

    avi_stream2fourcc(tag, stream);

    if(flags & AV_PKT_FLAG_KEY) //key frame
        i_flags = 0x10;

    if (stream->type == STREAM_TYPE_AUDIO)
       stream->audio_strm_length += size;


    avi_Index* idx = (avi_Index*) stream->indexes;
    int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
    int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
    if (idx->ents_allocated <= idx->entry)
    {
        idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*));
        if (!idx->cluster)
            return -1;
        idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(avi_Ientry));
        if (!idx->cluster[cl])
            return -1;
        idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE;
    }

    idx->cluster[cl][id].flags = i_flags;
    idx->cluster[cl][id].pos = io_get_offset(AVI->writer) - riff->movi_list;
    idx->cluster[cl][id].len = size;
    idx->entry++;


    io_write_4cc(AVI->writer, tag);
    io_write_wl32(AVI->writer, size);
    io_write_buf(AVI->writer, data, size);
    if (size & 1)
        io_write_w8(AVI->writer, 0);

    io_flush_buffer(AVI->writer);

    return 0;
}
Exemple #4
0
static int avi_write_counters(avi_Context* AVI, avi_RIFF* riff)
{
    int n, nb_frames = 0;
    io_flush_buffer(AVI->writer);

	//int time_base_num = AVI->time_base_num;
	//int time_base_den = AVI->time_base_den;

    int64_t file_size = io_get_offset(AVI->writer);//avi_tell(AVI);
    fprintf(stderr, "AVI: file size = %" PRIu64 "\n", file_size);

    for(n = 0; n < AVI->stream_list_size; n++)
    {
        io_Stream *stream = get_stream(AVI->stream_list, n);

		if(stream->rate_hdr_strm <= 0)
        {
			fprintf(stderr, "AVI: stream rate header pos not valid\n");
		}
		else
		{
			io_seek(AVI->writer, stream->rate_hdr_strm);

			if(stream->type == STREAM_TYPE_VIDEO && AVI->fps > 0.001)
			{
				uint32_t rate =(uint32_t) FRAME_RATE_SCALE * lrintf(AVI->fps);
				fprintf(stderr,"AVI: storing rate(%i)\n",rate);
				io_write_wl32(AVI->writer, rate);
			}
		}

        if(stream->frames_hdr_strm <= 0)
        {
			fprintf(stderr, "AVI: stream frames header pos not valid\n");
		}
		else
		{
			io_seek(AVI->writer, stream->frames_hdr_strm);

			if(stream->type == STREAM_TYPE_VIDEO)
			{
				io_write_wl32(AVI->writer, stream->packet_count);
				nb_frames = MAX(nb_frames, stream->packet_count);
			}
			else
			{
				int sampsize = avi_audio_sample_size(stream);
				io_write_wl32(AVI->writer, 4*stream->audio_strm_length/sampsize);
			}
		}
    }
    
    avi_RIFF* riff_1 = avi_get_riff(AVI, 1);
    if(riff_1->id == 1) /*should always be true*/
    {
        if(riff_1->time_delay_off <= 0)
        {
			fprintf(stderr, "AVI: riff main header pos not valid\n");
        }
        else
        {
			uint32_t us_per_frame = 1000; //us
			if(AVI->fps > 0.001)
				us_per_frame=(uint32_t) lrintf(1000000.0 / AVI->fps); 
		
			AVI->avi_flags |= AVIF_HASINDEX;
			
			io_seek(AVI->writer, riff_1->time_delay_off);
			io_write_wl32(AVI->writer, us_per_frame);      // time_per_frame
			io_write_wl32(AVI->writer, 0);                 // data rate
			io_write_wl32(AVI->writer, 0);                 // Padding multiple size (2048)
			io_write_wl32(AVI->writer, AVI->avi_flags);    // parameter Flags
			//io_seek(AVI->writer, riff_1->frames_hdr_all);
			io_write_wl32(AVI->writer, nb_frames);
		}
    }
    
	//return to position (EOF)
    io_seek(AVI->writer, file_size);

    return 0;
}