Example #1
0
/*
 * initialization of the file muxer
 * args:
 *   encoder_ctx - pointer to encoder context
 *   filename - video filename
 *
 * asserts:
 *   encoder_ctx is not null
 *   encoder_ctx->enc_video_ctx is not null
 *
 * returns: none
 */
void encoder_muxer_init(encoder_context_t *encoder_ctx, const char *filename)
{
	/*assertions*/
	assert(encoder_ctx != NULL);
	assert(encoder_ctx->enc_video_ctx != NULL);

	encoder_codec_data_t *video_codec_data = (encoder_codec_data_t *) encoder_ctx->enc_video_ctx->codec_data;

	int video_codec_id = AV_CODEC_ID_NONE;

	if(encoder_ctx->video_codec_ind == 0) /*no codec_context*/
	{
		switch(encoder_ctx->input_format)
		{
			case V4L2_PIX_FMT_H264:
				video_codec_id = AV_CODEC_ID_H264;
				break;
		}
	}
	else if(video_codec_data)
	{
		video_codec_id = video_codec_data->codec_context->codec_id;
	}

	if(verbosity > 1)
		printf("ENCODER: initializing muxer(%i)\n", encoder_ctx->muxer_id);

	switch (encoder_ctx->muxer_id)
	{
		case ENCODER_MUX_AVI:
			if(avi_ctx != NULL)
			{
				avi_destroy_context(avi_ctx);
				avi_ctx = NULL;
			}
			avi_ctx = avi_create_context(filename);

			/*add video stream*/
			video_stream = avi_add_video_stream(
				avi_ctx,
				encoder_ctx->video_width,
				encoder_ctx->video_height,
				encoder_ctx->fps_den,
				encoder_ctx->fps_num,
				video_codec_id);

			if(video_codec_id == AV_CODEC_ID_THEORA && video_codec_data)
			{
				video_stream->extra_data = (uint8_t *) video_codec_data->codec_context->extradata;
				video_stream->extra_data_size = video_codec_data->codec_context->extradata_size;
			}

			/*add audio stream*/
			if(encoder_ctx->enc_audio_ctx != NULL &&
				encoder_ctx->audio_channels > 0)
			{
				encoder_codec_data_t *audio_codec_data = (encoder_codec_data_t *) encoder_ctx->enc_audio_ctx->codec_data;
				if(audio_codec_data)
				{
					int acodec_ind = get_audio_codec_list_index(audio_codec_data->codec_context->codec_id);
					/*sample size - only used for PCM*/
					int32_t a_bits = encoder_get_audio_bits(acodec_ind);
					/*bit rate (compressed formats)*/
					int32_t b_rate = encoder_get_audio_bit_rate(acodec_ind);

					audio_stream = avi_add_audio_stream(
						avi_ctx,
						encoder_ctx->audio_channels,
						encoder_ctx->audio_samprate,
						a_bits,
						b_rate,
						audio_codec_data->codec_context->codec_id,
						encoder_ctx->enc_audio_ctx->avi_4cc);

					if(audio_codec_data->codec_context->codec_id == AV_CODEC_ID_VORBIS)
					{
						audio_stream->extra_data = (uint8_t *) audio_codec_data->codec_context->extradata;
						audio_stream->extra_data_size = audio_codec_data->codec_context->extradata_size;
					}
				}
			}

			/* add first riff header */
			avi_add_new_riff(avi_ctx);

			break;

		default:
		case ENCODER_MUX_MKV:
		case ENCODER_MUX_WEBM:
			if(mkv_ctx != NULL)
			{
				mkv_destroy_context(mkv_ctx);
				mkv_ctx = NULL;
			}
			mkv_ctx = mkv_create_context(filename, encoder_ctx->muxer_id);

			/*add video stream*/
			video_stream = mkv_add_video_stream(
				mkv_ctx,
				encoder_ctx->video_width,
				encoder_ctx->video_height,
				encoder_ctx->fps_den,
				encoder_ctx->fps_num,
				video_codec_id);

			video_stream->extra_data_size = encoder_set_video_mkvCodecPriv(encoder_ctx);

			if(video_stream->extra_data_size > 0)
			{
				video_stream->extra_data = (uint8_t *) encoder_get_video_mkvCodecPriv(encoder_ctx->video_codec_ind);
				if(encoder_ctx->input_format == V4L2_PIX_FMT_H264)
					video_stream->h264_process = 1; //we need to process NALU marker
			}

			/*add audio stream*/
			if(encoder_ctx->enc_audio_ctx != NULL &&
				encoder_ctx->audio_channels > 0)
			{
				encoder_codec_data_t *audio_codec_data = (encoder_codec_data_t *) encoder_ctx->enc_audio_ctx->codec_data;
				if(audio_codec_data)
				{
					mkv_ctx->audio_frame_size = audio_codec_data->codec_context->frame_size;

					/*sample size - only used for PCM*/
					int32_t a_bits = encoder_get_audio_bits(encoder_ctx->audio_codec_ind);
					/*bit rate (compressed formats)*/
					int32_t b_rate = encoder_get_audio_bit_rate(encoder_ctx->audio_codec_ind);

					audio_stream = mkv_add_audio_stream(
						mkv_ctx,
						encoder_ctx->audio_channels,
						encoder_ctx->audio_samprate,
						a_bits,
						b_rate,
						audio_codec_data->codec_context->codec_id,
						encoder_ctx->enc_audio_ctx->avi_4cc);

					audio_stream->extra_data_size = encoder_set_audio_mkvCodecPriv(encoder_ctx);

					if(audio_stream->extra_data_size > 0)
						audio_stream->extra_data = encoder_get_audio_mkvCodecPriv(encoder_ctx->audio_codec_ind);
				}
			}

			/* write the file header */
			mkv_write_header(mkv_ctx);

			break;

	}
}
Example #2
0
static int initVideoFile(struct ALL_DATA *all_data, void* lav_data)
{
	//struct GWIDGET *gwidget = all_data->gwidget;
	struct paRecordData *pdata = all_data->pdata;
	struct GLOBAL *global = all_data->global;
	struct vdIn *videoIn = all_data->videoIn;
	struct VideoFormatData *videoF = all_data->videoF;
	
	io_Stream *vstream, *astream;
	struct lavcData **lavc_data = (struct lavcData **) lav_data;

	videoF->vcodec = get_vcodec_id(global->VidCodec);
	videoF->acodec = get_acodec_id(global->AudCodec);
	videoF->keyframe = 0;
	int ret = 0;

	__LOCK_MUTEX(__VMUTEX);
		gboolean capVid = videoIn->capVid;
	__UNLOCK_MUTEX(__VMUTEX);

	/*alloc video ring buffer*/
	alloc_videoBuff(all_data);

	if(isLavcCodec(global->VidCodec))
		*lavc_data = init_lavc(global->width, global->height, global->fps_num, global->fps, global->VidCodec);


	switch (global->VidFormat)
	{
		case AVI_FORMAT:
			if(videoF->avi != NULL)
			{
				avi_destroy_context(videoF->avi);
				videoF->avi = NULL;
			}
			videoF->avi = avi_create_context(videoIn->VidFName);

			if(!videoF->avi)
			{
				g_printerr("Error: Couldn't create AVI context.\n");
				capVid = FALSE; /*don't start video capture*/
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				return(-1);
			}

			vstream = avi_add_video_stream(videoF->avi,
								global->width,
								global->height,
								global->fps,
								videoF->vcodec,
								get_vid4cc(global->VidCodec));

			if(videoF->vcodec == AV_CODEC_ID_THEORA)
			{
				vstream->extra_data = (BYTE*) (*lavc_data)->codec_context->extradata;
				vstream->extra_data_size = (*lavc_data)->codec_context->extradata_size;
			}

			if(global->Sound_enable > 0)
			{
				/*get channels and sample rate*/
				set_sound(global, pdata);

				/*sample size - only used for PCM*/
				int32_t a_bits = get_aud_bits(global->AudCodec);
				/*bit rate (compressed formats)*/
				int32_t b_rate = get_aud_bit_rate(global->AudCodec);

				astream = avi_add_audio_stream(videoF->avi,
								global->Sound_NumChan,
								global->Sound_SampRate,
								a_bits,
								b_rate,
								videoF->acodec,
								global->Sound_Format);

				if(videoF->acodec == AV_CODEC_ID_VORBIS)
				{
						astream->extra_data = (BYTE*) pdata->lavc_data->codec_context->extradata;
						astream->extra_data_size = pdata->lavc_data->codec_context->extradata_size;
				}

			}
			/* add first riff header */
			avi_add_new_riff(videoF->avi);

			/* start video capture*/
			capVid = TRUE;
			__LOCK_MUTEX(__VMUTEX);
				videoIn->capVid = capVid;
			__UNLOCK_MUTEX(__VMUTEX);
			pdata->capVid = capVid;

			/* start sound capture*/
			if(global->Sound_enable > 0 && init_sound (pdata))
			{
				//FIXME: enable capture button
				g_printerr("Audio initialization error\n");
				global->Sound_enable=0;
			}
			break;

		case WEBM_FORMAT:
		case MKV_FORMAT:
			if(videoF->mkv != NULL)
			{
				mkv_destroy_context(videoF->mkv);
				videoF->mkv = NULL;
			}
			videoF->mkv = mkv_create_context(videoIn->VidFName, global->VidFormat);

			if(!videoF->mkv)
			{
				g_printerr("Error: Couldn't create MKV context.\n");
				capVid = FALSE; /*don't start video capture*/
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				return(-1);
			}

			vstream = mkv_add_video_stream(videoF->mkv,
									global->width,
									global->height,
									videoF->vcodec);


			vstream->extra_data_size = set_mkvCodecPriv(global->VidCodec, global->width, global->height, *lavc_data);
			if(vstream->extra_data_size > 0)
				vstream->extra_data = get_mkvCodecPriv(global->VidCodec);

			if(global->Sound_enable > 0)
			{
				/*get channels and sample rate*/
				set_sound(global, pdata);

				/*sample size - only used for PCM*/
				int32_t a_bits = get_aud_bits(global->AudCodec);
				/*bit rate (compressed formats)*/
				int32_t b_rate = get_aud_bit_rate(global->AudCodec);

				astream = mkv_add_audio_stream(
								videoF->mkv,
								pdata->channels,
								pdata->samprate,
								a_bits,
								b_rate,
								videoF->acodec,
								global->Sound_Format);

				astream->extra_data_size = set_mkvACodecPriv(
								global->AudCodec,
								pdata->samprate,
								pdata->channels,
								pdata->lavc_data);

				if(astream->extra_data_size > 0)
					astream->extra_data = get_mkvACodecPriv(global->AudCodec);


			}

			/** write the file header */
			mkv_write_header(videoF->mkv);

			/* start video capture*/
			capVid = TRUE;
			__LOCK_MUTEX(__VMUTEX);
				videoIn->capVid = capVid;
			__UNLOCK_MUTEX(__VMUTEX);
			pdata->capVid = capVid;

			/* start sound capture*/
			if(global->Sound_enable > 0 && init_sound (pdata))
			{
				//FIXME: enable capture button
				g_printerr("Audio initialization error\n");
				global->Sound_enable=0;
			}
			break;

		default:

			break;
	}

	return (ret);
}
Example #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;
}