Exemple #1
0
int	  mk_startFrame(mk_Writer *w) {
  if (mk_flushFrame(w) < 0)
    return -1;

  w->in_frame = 1;
  w->keyframe = 0;

  return 0;
}
Exemple #2
0
int mk_startFrame(mk_Writer *w, mk_Track *track)
{
	if (mk_flushFrame(w, track) < 0)
		return -1;

	track->in_frame = 1;
	track->frame.keyframe = 0;
	track->frame.lacing = MK_LACING_NONE;
	track->frame.lacing_num_frames = 0;
	track->frame.lacing_sizes = NULL;

	return 0;
}
Exemple #3
0
int	  mk_close(mk_Writer *w) {
  int	ret = 0;
  if (mk_flushFrame(w) < 0 || mk_closeCluster(w) < 0)
    ret = -1;
  if (w->wrote_header) {
    fseek(w->fp, w->duration_ptr, SEEK_SET);
    if (mk_writeFloatRaw(w->root, (float)((double)(w->max_frame_tc+w->def_duration) / w->timescale)) < 0 ||
	mk_flushContextData(w->root) < 0)
      ret = -1;
  }
  mk_destroyContexts(w);
  fclose(w->fp);
  free(w);
  return ret;
}
Exemple #4
0
int mk_close(mk_Writer *w)
{
	int i, ret = 0;
	mk_Track *tk;
	int64_t max_frame_tc = w->tracks_arr[0]->max_frame_tc;
	uint64_t segment_size = 0;
	unsigned char c_size[8];
	unsigned char segment_uid[16];

	md5_finish(&w->segment_md5, segment_uid);

	for (i = w->num_tracks - 1; i >= 0; i--) {
		tk = w->tracks_arr[i];
		if (mk_flushFrame(w, tk) < 0)
			ret = -1;
	}

	if (mk_closeCluster(w) < 0)
		ret = -1;

	w->seek_data.cues = w->f_pos - w->segment_ptr;
	if (mk_closeContext(w->cues, 0) < 0)
		ret = -1;
	if (mk_flushContextData(w->root) < 0)
		ret = -1;

	if (w->cluster.seekhead) {
		w->seek_data.seekhead = w->f_pos - w->segment_ptr;
		if (mk_closeContext(w->cluster.seekhead, 0) < 0)
			ret = -1;
		if (mk_flushContextData(w->root) < 0)
			ret = -1;
	}

	if (w->attachments != NULL) {
		w->seek_data.attachments = w->f_pos - w->segment_ptr;
		mk_writeAttachments(w);
		if (mk_flushContextData(w->root) < 0)
			ret = -1;
	}

	if (w->tags != NULL) {
		w->seek_data.tags = w->f_pos - w->segment_ptr;
		mk_writeTags(w);
		if (mk_flushContextData(w->root) < 0)
			ret = -1;
	}

	if (w->chapters != NULL) {
		if (w->vlc_compat) {
			if (mk_flushContextData(w->root) < 0)
				ret = -1;
			if (mk_seekFile(w, w->segment_ptr + RESERVED_SEEKHEAD + 3) < 0)
				ret = -1;
		}
		w->seek_data.chapters = w->f_pos - w->segment_ptr;
		mk_writeChapters(w);
		if (mk_flushContextData(w->root) < 0)
			ret = -1;
		if (w->vlc_compat) {
			if (mk_writeVoid(w->root, (RESERVED_CHAPTERS - (w->f_pos - w->segment_ptr - RESERVED_SEEKHEAD - 3))) < 0)
				ret = -1;
			if (mk_flushContextData(w->root) < 0)
				ret = -1;
		}
	}

	if (w->wrote_header) {
		if (w->vlc_compat) {
			if (mk_seekFile(w, w->segment_ptr) < 0)
				ret = -1;
		}

		if (mk_writeSeekHead(w, &w->seek_data.seekhead) < 0)
			ret = -1;
		w->seek_data.seekhead -= w->segment_ptr;

		if (w->vlc_compat) {
			if (mk_flushContextData(w->root) < 0)
				ret = -1;
			if (mk_writeVoid(w->root, (RESERVED_SEEKHEAD - (w->f_pos - w->segment_ptr))) < 0)
				ret = -1;
		}

		if (mk_flushContextData(w->root) < 0)
			ret = -1;

		if (!w->vlc_compat) {
			int i = w->seek_data.segmentinfo;
			w->seek_data.segmentinfo = 0;
			w->seek_data.tracks = 0;
			w->seek_data.cues = 0;
			w->seek_data.chapters = 0;
			w->seek_data.attachments = 0;
			w->seek_data.tags = 0;
			if (mk_seekFile(w, w->segment_ptr) < 0)
				ret = -1;
			if (mk_writeSeekHead(w, NULL) < 0 || mk_flushContextData(w->root) < 0)
				ret = -1;
			// The conditional below is easier to understand, but incorrect
			// because f_pos is unsigned and causes the lhs to be evaluated
			// as an unsigned quantity.
			// if (((i + w->segment_ptr) - w->f_pos - 2) > 1)
			if ((i + w->segment_ptr) > (w->f_pos + 3))
				if (mk_writeVoid(w->root, (i + w->segment_ptr) - w->f_pos - 2) < 0
					|| mk_flushContextData(w->root) < 0)
					ret = -1;
		}

		if (mk_seekFile(w, w->duration_ptr) < 0)
			ret = -1;
		if (mk_writeFloatRaw(w->root,
							 (float) ((double) (max_frame_tc + w->def_duration) /
							 w->timescale)) < 0
			|| mk_flushContextData(w->root) < 0)
			ret = -1;
		if (mk_seekFile(w, w->segment_ptr - 8) < 0)
			ret = -1;
		segment_size = w->f_eof - w->segment_ptr;
		for (i = 7; i > 0; --i)
			c_size[i] = segment_size >> (8 * (7 - i));
		c_size[i] = 0x01;
		if (mk_appendContextData(w->root, &c_size, 8) < 0 ||
			mk_flushContextData(w->root) < 0)
			ret = -1;
		if (mk_seekFile(w, w->segmentuid_ptr) < 0)
			ret = -1;
		if (mk_writeBin(w->root, MATROSKA_ID_SEGMENTUID, segment_uid,
						sizeof(segment_uid)) < 0 ||
			mk_flushContextData(w->root) < 0)
			ret = -1;
	}

    /* update any track private data that may have changed */
	for (i = w->num_tracks - 1; i >= 0; i--) {
		tk = w->tracks_arr[i];
		if (tk->private_data_size && tk->private_data)
		{
			if (mk_seekFile(w, tk->private_data_ptr) < 0)
				ret = -1;
			if (mk_writeBin(w->root, MATROSKA_ID_CODECPRIVATE,
							tk->private_data, tk->private_data_size) < 0 ||
				mk_flushContextData(w->root) < 0)
				ret = -1;
			free(tk->private_data);
        }
		w->tracks_arr[i] = NULL;
		--w->num_tracks;
		free(tk);
	}

	if (mk_closeContext(w->root, 0) < 0)
		ret = -1;
	mk_destroyContexts(w);
	fclose(w->fp);
	free(w->tracks_arr);
	free(w);

	return ret;
}
Exemple #5
0
static int MKVMux(hb_mux_object_t *m, hb_mux_data_t *mux_data, hb_buffer_t *buf)
{
    char chapter_name[1024];
    hb_chapter_t *chapter_data;
    uint64_t timecode = 0;
    ogg_packet *op    = NULL;
    hb_job_t *job     = m->job;

    if (mux_data == job->mux_data)
    {
        /* Video */
        timecode = buf->s.start * TIMECODE_SCALE;

        if (job->chapter_markers && buf->s.new_chap)
        {
            // reached chapter N, write marker for chapter N-1
            mux_data->current_chapter = buf->s.new_chap - 1;

            // chapter numbers start at 1, but the list starts at 0
            chapter_data = hb_list_item(job->list_chapter,
                                        mux_data->current_chapter - 1);

            // make sure we're not writing a chapter that has 0 length
            if (chapter_data != NULL && mux_data->prev_chapter_tc < timecode)
            {
                if (chapter_data->title != NULL)
                {
                    snprintf(chapter_name, 1023, "%s", chapter_data->title);
                }
                else
                {
                    snprintf(chapter_name, 1023, "Chapter %d",
                             mux_data->current_chapter);
                }
                mk_createChapterSimple(m->file,
                                       mux_data->prev_chapter_tc,
                                       mux_data->prev_chapter_tc, chapter_name);
            }
            mux_data->prev_chapter_tc = timecode;
        }

        if (job->vcodec == HB_VCODEC_THEORA)
        {
            /* ughhh, theora is a pain :( */
            op = (ogg_packet *)buf->data;
            op->packet = buf->data + sizeof( ogg_packet );
            if (mk_startFrame(m->file, mux_data->track) < 0)
            {
                hb_error( "Failed to write frame to output file, Disk Full?" );
                *job->die = 1;
            }
            mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
            mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
            hb_buffer_close( &buf );
            return 0;
        }
    }
    else if (mux_data->subtitle)
    {
        if( mk_startFrame(m->file, mux_data->track) < 0)
        {
            hb_error("Failed to write frame to output file, Disk Full?");
            *job->die = 1;
        }
        uint64_t duration;
        timecode = buf->s.start * TIMECODE_SCALE;
        if (buf->s.stop <= buf->s.start)
        {
            duration = 0;
        }
        else
        {
            duration = buf->s.stop * TIMECODE_SCALE - timecode;
        }
        mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
        mk_setFrameFlags(m->file, mux_data->track, timecode, 1, duration);
        mk_flushFrame(m->file, mux_data->track);
        hb_buffer_close(&buf);
        return 0;
    }
    else
    {
        /* Audio */
        timecode = buf->s.start * TIMECODE_SCALE;
        if (mux_data->codec == HB_ACODEC_VORBIS)
        {
            /* ughhh, vorbis is a pain :( */
            op = (ogg_packet *)buf->data;
            op->packet = buf->data + sizeof( ogg_packet );
            if (mk_startFrame(m->file, mux_data->track))
            {
                hb_error( "Failed to write frame to output file, Disk Full?" );
                *job->die = 1;
            }
            mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
            mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
            hb_buffer_close( &buf );
            return 0;
        }
    }

    if( mk_startFrame(m->file, mux_data->track) < 0)
    {
        hb_error( "Failed to write frame to output file, Disk Full?" );
        *job->die = 1;
    }
    mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
    mk_setFrameFlags(m->file, mux_data->track, timecode,
                     (((job->vcodec == HB_VCODEC_X264 || 
                        (job->vcodec & HB_VCODEC_FFMPEG_MASK)) && 
                       mux_data == job->mux_data) ? 
                            (buf->s.frametype == HB_FRAME_IDR) : 
                            ((buf->s.frametype & HB_FRAME_KEY) != 0)), 0 );
    hb_buffer_close( &buf );
    return 0;
}