コード例 #1
0
ファイル: a52.c プロジェクト: ifroz/rockbox
/* this is called for each file to process */
enum codec_status codec_run(void)
{
    size_t n;
    unsigned char *filebuf;
    int sample_loc;
    intptr_t param;

    if (codec_init())
        return CODEC_ERROR;

    ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
    codec_set_replaygain(ci->id3);
    
    /* Intialise the A52 decoder and check for success */
    state = a52_init(0);

    samplesdone = 0;

    /* The main decoding loop */
    if (ci->id3->offset) {
        if (ci->seek_buffer(ci->id3->offset)) {
            samplesdone = (ci->id3->offset / ci->id3->bytesperframe) *
                A52_SAMPLESPERFRAME;
            ci->set_elapsed(samplesdone/(ci->id3->frequency / 1000));
        }
    }
    else {
        ci->seek_buffer(ci->id3->first_frame_offset);
        ci->set_elapsed(0);
    }

    while (1) {
        enum codec_command_action action = ci->get_command(&param);

        if (action == CODEC_ACTION_HALT)
            break;

        if (action == CODEC_ACTION_SEEK_TIME) {
            sample_loc = param/1000 * ci->id3->frequency;

            if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) {
                samplesdone = sample_loc;
                ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
            }
            ci->seek_complete();
        }

        filebuf = ci->request_buffer(&n, BUFFER_SIZE);

        if (n == 0) /* End of Stream */
            break;
  
        a52_decode_data(filebuf, filebuf + n);
        ci->advance_buffer(n);
    }

    return CODEC_OK;
}
コード例 #2
0
ファイル: a52.c プロジェクト: claymodel/rockbox
/* this is the codec entry point */
enum codec_status codec_main(void)
{
    size_t n;
    unsigned char *filebuf;
    int sample_loc;
    int retval;

    /* Generic codec initialisation */
    ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
    ci->configure(DSP_SET_SAMPLE_DEPTH, 28);

next_track:
    retval = CODEC_OK;

    if (codec_init()) {
        retval = CODEC_ERROR;
        goto exit;
    }

    if (codec_wait_taginfo() != 0)
        goto request_next_track;

    ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
    codec_set_replaygain(ci->id3);
    
    /* Intialise the A52 decoder and check for success */
    state = a52_init(0);

    /* The main decoding loop */
    if (ci->id3->offset) {
        if (ci->seek_buffer(ci->id3->offset)) {
            samplesdone = (ci->id3->offset / ci->id3->bytesperframe) *
                A52_SAMPLESPERFRAME;
            ci->set_elapsed(samplesdone/(ci->id3->frequency / 1000));
        }
    }
    else {
        samplesdone = 0;
    }

    while (1) {
        if (ci->stop_codec || ci->new_track)
            break;

        if (ci->seek_time) {
            sample_loc = (ci->seek_time - 1)/1000 * ci->id3->frequency;

            if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) {
                samplesdone = sample_loc;
                ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
            }
            ci->seek_complete();
        }

        filebuf = ci->request_buffer(&n, BUFFER_SIZE);

        if (n == 0) /* End of Stream */
            break;
  
        a52_decode_data(filebuf, filebuf + n);
        ci->advance_buffer(n);
    }

request_next_track:
    if (ci->request_next_track())
        goto next_track;

exit:
    a52_free(state);
    return retval;
}
コード例 #3
0
ファイル: video.c プロジェクト: cgbarnwell/mvpmc
void*
audio_write_start(void *arg)
{
	int idle = 1;
	pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
	int len;
	sigset_t sigs;
	demux_attr_t *attr;
	video_info_t *vi;

	signal(SIGURG, sighandler);
	sigemptyset(&sigs);
	sigaddset(&sigs, SIGURG);
	pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);

	pthread_mutex_lock(&mutex);

	printf("audio write thread started (pid %d)\n", getpid());
	pthread_cond_wait(&video_cond, &mutex);

	while (1) {
		while (seeking || jumping)
			pthread_cond_wait(&video_cond, &mutex);

		while (!video_playing) {
			pcm_decoded = 0;
			empty_ac3();
			if ( !(idle) ) {
				sem_post(&write_threads_idle_sem);
				idle = 1;
				printf("audio write thread sleeping...\n");
			}
			pthread_cond_wait(&video_cond, &mutex);
		}
		if ( idle ) {
			sem_wait(&write_threads_idle_sem);
			idle = 0;
			printf("audio write thread running\n");
		}

		if (running_replaytv) {
			attr = demux_get_attr(handle);
			vi = &attr->video.stats.info.video;
			if (attr->audio.type != audio_type) {
            // JBH: FIX ME: This code never gets hit
				audio_type = attr->audio.type;
				switch (audio_type) {
				case AUDIO_MODE_AC3:
				case AUDIO_MODE_PCM:
					audio_output = AV_AUDIO_PCM;
					printf("switch to PCM audio\n");
					break;
				default:
					av_set_audio_type(audio_type);
					audio_output = AV_AUDIO_MPEG;
					printf("switch to MPEG audio\n");
					break;
				}
				av_set_audio_output(audio_output);
			}
		}

		switch (audio_type) {
		case AUDIO_MODE_MPEG1_PES:
		case AUDIO_MODE_MPEG2_PES:
		case AUDIO_MODE_ES:
			if (jit_mode == 0) {
				if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0)
					pthread_cond_broadcast(&video_cond);
				else
					pthread_cond_wait(&video_cond, &mutex);
			} else {
			    int flags, duration;
			    len=DEMUX_JIT_WRITE_AUDIO(handle, fd_audio,
						get_cur_vid_stc(),jit_mode,
						&flags,&duration);
			    if(flags & 4)
			    {
				/*4 is the same as 1 followed by 2*/
				flags = (flags | 1 | 2) & ~4;
			    }
			    if(flags & 1)
			    {
				av_pause_video();
			    }
			    if((flags & 2) && !paused)
			    {
				if(duration <= 10)
				    video_unpause_timer_callback(pause_widget);
				else
				    mvpw_set_timer(pause_widget,
				       video_unpause_timer_callback, duration);
			    }
			    if(flags & 8)
			    {
				usleep(duration*1000);
			    }


			    if(len > 0)
				    pthread_cond_broadcast(&video_cond);
			    else if(!(flags & 8))
				    pthread_cond_wait(&video_cond, &mutex);
			}
			break;
		case AUDIO_MODE_PCM:
			/*
			 * XXX: PCM audio does not work yet
			 */
			pthread_cond_wait(&video_cond, &mutex);
			break;
		case AUDIO_MODE_AC3:
			if (audio_output_mode == AUD_OUTPUT_PASSTHRU ) {
				if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0)
					pthread_cond_broadcast(&video_cond);
				else
					pthread_cond_wait(&video_cond, &mutex);
				break;
			}
			if (ac3more == -1)
				ac3more = a52_decode_data(NULL, NULL,
							  pcm_decoded);
			if (ac3more == 1) {
				ac3more = a52_decode_data(ac3buf,
							  ac3buf + ac3len,
							  pcm_decoded);
				if (ac3more == 1) {
					pthread_cond_wait(&video_cond, &mutex);
					break;
				}
			}

			if (ac3more == 0) {
				ac3len = demux_get_audio(handle, ac3buf,
							 sizeof(ac3buf));
				ac3more = 1;
			}

			if (ac3more == 0)
				pthread_cond_wait(&video_cond, &mutex);
			else
				pthread_cond_broadcast(&video_cond);

			pcm_decoded = 1;
			break;
		}
	}

	return NULL;
}
コード例 #4
0
ファイル: a52_rm.c プロジェクト: 4nykey/rockbox
/* this is called for each file to process */
enum codec_status codec_run(void)
{
    size_t n;
    uint8_t *filebuf;
    int consumed, packet_offset;
    int playback_on = -1;
    size_t resume_offset;
    intptr_t param;
    enum codec_command_action action = CODEC_ACTION_NULL;

    if (codec_init()) {
        return CODEC_ERROR;
    }

    resume_offset = ci->id3->offset;

    ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
    codec_set_replaygain(ci->id3);

    ci->seek_buffer(ci->id3->first_frame_offset);

    /* Intializations */
    state = a52_init(0);
    ci->memset(&rmctx,0,sizeof(RMContext)); 
    ci->memset(&pkt,0,sizeof(RMPacket));
    init_rm(&rmctx);

    samplesdone = 0;

    /* check for a mid-track resume and force a seek time accordingly */
    if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) {
        resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
        /* put number of subpackets to skip in resume_offset */
        resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE);
        param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
        action = CODEC_ACTION_SEEK_TIME;
    }
    else {
        /* Seek to the first packet */
        ci->set_elapsed(0);
        ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE );
    }

    /* The main decoding loop */
    while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) {
        if (action == CODEC_ACTION_NULL)
            action = ci->get_command(&param);

        if (action == CODEC_ACTION_HALT)
            break;

        if (action == CODEC_ACTION_SEEK_TIME) {
            packet_offset = param / ((rmctx.block_align*8*1000)/rmctx.bit_rate);
            ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE +
                            packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE));
            rmctx.audio_pkt_cnt = packet_offset;
            samplesdone = (rmctx.sample_rate/1000 * param);
            ci->set_elapsed(samplesdone/(frequency/1000));
            ci->seek_complete();
        }

        action = CODEC_ACTION_NULL;

        filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE);
        consumed = rm_get_packet(&filebuf, &rmctx, &pkt);

        if(consumed < 0 && playback_on != 0) {
            if(playback_on == -1) {
            /* Error only if packet-parsing failed and playback hadn't started */
                DEBUGF("rm_get_packet failed\n");
                return CODEC_ERROR;
            }
            else {
                break;
            }
        }

        playback_on = 1;
        a52_decode_data(filebuf, filebuf + rmctx.block_align);
        ci->advance_buffer(pkt.length);
    }

    return CODEC_OK;
}