Example #1
0
mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec)
{
    int size_buffer, size_chunk, copied;

    if (mpeg2dec->action) {
	mpeg2_state_t state;

	state = mpeg2dec->action (mpeg2dec);
	if ((int)state > (int)STATE_INTERNAL_NORETURN)
	    return state;
    }

    while (1) {
	while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) <
	       mpeg2dec->nb_decode_slices) {
	    size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
	    size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
			  mpeg2dec->chunk_ptr);
	    if (size_buffer <= size_chunk) {
		copied = copy_chunk (mpeg2dec, size_buffer);
		if (!copied) {
		    mpeg2dec->bytes_since_tag += size_buffer;
		    mpeg2dec->chunk_ptr += size_buffer;
		    return STATE_BUFFER;
		}
	    } else {
		copied = copy_chunk (mpeg2dec, size_chunk);
		if (!copied) {
		    /* filled the chunk buffer without finding a start code */
		    mpeg2dec->bytes_since_tag += size_chunk;
		    mpeg2dec->action = seek_chunk;
		    return STATE_INVALID;
		}
	    }
	    mpeg2dec->bytes_since_tag += copied;

	    mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code,
			 mpeg2dec->chunk_start);
	    mpeg2dec->code = mpeg2dec->buf_start[-1];
	    mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
	}
	if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1)
	    break;
	if (seek_chunk (mpeg2dec) == STATE_BUFFER)
	    return STATE_BUFFER;
    }

    mpeg2dec->action = mpeg2_seek_header;
    switch (mpeg2dec->code) {
    case 0x00:
	return mpeg2dec->state;
    case 0xb3:
    case 0xb7:
    case 0xb8:
	return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID;
    default:
	mpeg2dec->action = seek_chunk;
	return STATE_INVALID;
    }
}
Example #2
0
static size_t copy_bundle2_chunk(FILE *in, FILE *out)
{
	return copy_chunk(0, in, out);
}
Example #3
0
static size_t copy_changegroup_chunk(FILE *in, FILE *out)
{
	return copy_chunk(4, in, out);
}
Example #4
0
mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec)
{
    static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = {
	mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data,
	mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop
    };
    int size_buffer, size_chunk, copied;

    mpeg2dec->action = mpeg2_parse_header;
    mpeg2dec->info.user_data = NULL;	mpeg2dec->info.user_data_len = 0;
    while (1) {
	size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
	size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
		      mpeg2dec->chunk_ptr);
	if (size_buffer <= size_chunk) {
	    copied = copy_chunk (mpeg2dec, size_buffer);
	    if (!copied) {
		mpeg2dec->bytes_since_tag += size_buffer;
		mpeg2dec->chunk_ptr += size_buffer;
		return STATE_BUFFER;
	    }
	} else {
	    copied = copy_chunk (mpeg2dec, size_chunk);
	    if (!copied) {
		/* filled the chunk buffer without finding a start code */
		mpeg2dec->bytes_since_tag += size_chunk;
		mpeg2dec->code = 0xb4;
		mpeg2dec->action = mpeg2_seek_header;
		return STATE_INVALID;
	    }
	}
	mpeg2dec->bytes_since_tag += copied;

	if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) {
	    mpeg2dec->code = mpeg2dec->buf_start[-1];
	    mpeg2dec->action = mpeg2_seek_header;
	    return STATE_INVALID;
	}

	mpeg2dec->code = mpeg2dec->buf_start[-1];
	switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) {

	/* state transition after a sequence header */
	case RECEIVED (0x00, STATE_SEQUENCE):
	case RECEIVED (0xb8, STATE_SEQUENCE):
	    mpeg2_header_sequence_finalize (mpeg2dec);
	    break;

	/* other legal state transitions */
	case RECEIVED (0x00, STATE_GOP):
	    mpeg2_header_gop_finalize (mpeg2dec);
	    break;
	case RECEIVED (0x01, STATE_PICTURE):
	case RECEIVED (0x01, STATE_PICTURE_2ND):
	    mpeg2_header_picture_finalize (mpeg2dec, mpeg2_accels);
	    mpeg2dec->action = mpeg2_header_slice_start;
	    break;

	/* legal headers within a given state */
	case RECEIVED (0xb2, STATE_SEQUENCE):
	case RECEIVED (0xb2, STATE_GOP):
	case RECEIVED (0xb2, STATE_PICTURE):
	case RECEIVED (0xb2, STATE_PICTURE_2ND):
	case RECEIVED (0xb5, STATE_SEQUENCE):
	case RECEIVED (0xb5, STATE_PICTURE):
	case RECEIVED (0xb5, STATE_PICTURE_2ND):
	    mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
	    continue;

	default:
	    mpeg2dec->action = mpeg2_seek_header;
	    return STATE_INVALID;
	}

	mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
	mpeg2dec->user_data_len = 0;
	return mpeg2dec->state;
    }
}
Example #5
0
static int probe_audio_tick_size(tystream_holder_t * tystream) {

	/* Iteration */
	int i;

	/* Chunks */
	chunk_t * chunks;
	chunk_t * right_audio_chunk;

	/* Counting variables */
	int nr_size;
	int nr_time;
	int nr_audio_pes;

	/* Total timediff and size */
	ticks_t total_time;
	ticks_t time_diff;
	ticks_t audio_median_tick_diff;
	int total_size;
	int med_size;

	/* Markers */
	int gotit;


	/* Init */
	chunks = tystream->chunks;
	right_audio_chunk=NULL;
	nr_size = 0;
	nr_time = 0;
	nr_audio_pes = 0;
	total_time = 0;
	gotit = 0;
	total_size = 0;

	//printf("Audio Tick size\n");

	while(chunks) {
		gotit = 0;
		for(i=0; i < chunks->nr_records; i++){
			if(chunks->record_header[i].type == tystream->right_audio) {
				/* okay so lets save  it - in junk_chunks */
				//printf("Audio Tick size copy %i\n", i);
				right_audio_chunk = copy_chunk(chunks);
				//printf("Audio Tick size copy finished %i\n", i);
				if(right_audio_chunk) {
					tystream->junk_chunks = add_chunk(tystream, right_audio_chunk, tystream->junk_chunks);
				}
				gotit = 1;
			} else if (chunks->record_header[i].type == tystream->wrong_audio) {
				gotit = 1;
			}

			if(gotit) {
				break;
			}
		}
		chunks = chunks->next;
	}


	if( tystream->junk_chunks == NULL) {
		/* Abort */
		LOG_ERROR("ABORTING \n");
		return(0);
	}

	right_audio_chunk = tystream->junk_chunks;

	//printf("Audio Tick size - 1\n");

	/* Okay so get the total size - two stage to remove unwanted values FIXME*/
	while(right_audio_chunk) {
		for(i=0; i < right_audio_chunk->nr_records; i++) {
			switch(right_audio_chunk->record_header[i].type){
				case 0x2c0:
				case 0x4c0:
				case 0x3c0:
				case 0x9c0:
					if(right_audio_chunk->record_header[i].size > 300 &&  right_audio_chunk->record_header[i].size < 2000) {
						nr_size++;
						total_size = total_size + right_audio_chunk->record_header[i].size;
						LOG_DEVDIAG1("Size is %i\n",right_audio_chunk->record_header[i].size );
						LOG_DEVDIAG1("Total Size is %i\n", total_size);
						
					}
					break;
			}
		}
		right_audio_chunk = right_audio_chunk->next;
	}

	if(!nr_size) {
		LOG_ERROR("Major error div by zero\n");
		return(0);
	}

	med_size = total_size / nr_size;

	//printf("Audio Tick size - 2\n");

	nr_size = 0;
	total_size = 0;
	right_audio_chunk = tystream->junk_chunks;

	while(right_audio_chunk) {
		for(i=0; i < right_audio_chunk->nr_records; i++) {
			switch(right_audio_chunk->record_header[i].type){
				case 0x2c0:
				case 0x4c0:
				case 0x3c0:
				case 0x9c0:
					if((int)right_audio_chunk->record_header[i].size > (med_size - 200) &&
					   (int)right_audio_chunk->record_header[i].size < (med_size + 200)) {
						nr_size++;
						total_size = total_size + right_audio_chunk->record_header[i].size;
						LOG_DEVDIAG1("Size is %i\n",right_audio_chunk->record_header[i].size );
						LOG_DEVDIAG1("Total Size is %i\n", total_size);
					}
					break;
			}
		}
		right_audio_chunk = right_audio_chunk->next;
	}

	if(!nr_size) {
		LOG_ERROR("Major error div by zero\n");
	}

	//printf("Audio Tick size - 3 \n");

	med_size = total_size / nr_size;

	tystream->med_size = med_size;

	/* This is the typical sizes of TIVO mpeg/ac3 audio
	 * Hence we want to control if we have a typical one
	 * if we don't we give a waring and tell the user to
	 * save the tystream. FIXME WE SHOULD EXIT
	 */
	if(med_size > 1532 && med_size < 1572) {
		tystream->std_audio_size = 1552;
		tystream->audio_frame_size = 1536;
		tystream->audio_type = DTIVO_AC3;
	} else if ( med_size > 840 && med_size < 910) {
		tystream->std_audio_size = 880;
		tystream->audio_frame_size = 864;
		tystream->audio_type = SA_MPEG;
	} else if ( med_size > 760 && med_size < 800) {
		tystream->std_audio_size = 780;
		tystream->audio_frame_size = 768;
		tystream->audio_type = DTIVO_MPEG_1;
	} else if ( med_size > 568 && med_size < 608) {
		tystream->std_audio_size = 588;
		tystream->audio_frame_size = 576;
		tystream->audio_type = DTIVO_MPEG_2;
	} else if ( med_size > 460 && med_size < 500) {
		tystream->std_audio_size = 492;
		tystream->audio_frame_size = 480;
		tystream->audio_type = DTIVO_MPEG_3;
	} else if ( med_size > 328 && med_size < 368) {
		/* This one is a bit of guess work FIXME */
		tystream->std_audio_size = 348;
		tystream->audio_frame_size = 336;
		tystream->audio_type = DTIVO_MPEG_4;
		LOG_ERROR("probe_audio_tick_size: PLEASE SEND A REPORT - SAVE THE TYSTREAM\n");
	} else {
		tystream->std_audio_size = 0;
		tystream->audio_frame_size = 0;
		tystream->audio_type = AUDIO_TYPE_UNKNOW;
		LOG_WARNING("probe_audio_tick_size: Warning: can't determine std audio size PLEASE SEND A REPORT - SAVE THE TYSTREAM\n");
	}

	/* Now we collect the median tickdiff of the audio stream */

	right_audio_chunk = tystream->junk_chunks;

	while(right_audio_chunk) {
		nr_audio_pes = get_nr_audio_pes(tystream, right_audio_chunk);
		for(i=0; i < nr_audio_pes - 2; i++) {
			time_diff = get_time_X(i + 1, right_audio_chunk, AUDIO, tystream)
				- get_time_X(i, right_audio_chunk, AUDIO, tystream);
			if(time_diff > 1000 && time_diff < 4000) {
				total_time = total_time + time_diff;
				nr_time++;
			}
		}
		right_audio_chunk = right_audio_chunk->next;
	}


	//printf("Out of Audio Tick\n");
	audio_median_tick_diff = total_time / nr_time;
	
	if(audio_median_tick_diff < 3245 && audio_median_tick_diff > 3235) {
		tystream->audio_median_tick_diff = 3240;
	} else if (audio_median_tick_diff < 2165 && audio_median_tick_diff > 2155) {
		tystream->audio_median_tick_diff = 2160;
	} else if (audio_median_tick_diff < 2885 && audio_median_tick_diff > 2875) {
		tystream->audio_median_tick_diff = 2880;
	} else {
		LOG_WARNING1("probe_audio_tick_size: Warning: can't determine audio_median_tick_diff "I64FORMAT"PLEASE SEND A REPORT - SAVE THE TYSTREAM\n", audio_median_tick_diff);
		return(0);
	}

	return(1);

}