int audiodec_init(aml_audio_dec_t *audec)
{
    int ret = 0;
    pthread_t    tid;
    adec_print("audiodec_init!");
    adec_message_pool_init(audec);
    get_output_func(audec);
    int nCodecType=audec->format;
    set_audio_decoder(audec);
    audec->format_changed_flag=0;
    if (get_audio_decoder() == AUDIO_ARC_DECODER) {
    		audec->adsp_ops.dsp_file_fd = -1;
		ret = pthread_create(&tid, NULL, (void *)adec_message_loop, (void *)audec);
    }
    else 
    {
		int codec_type=get_audio_decoder();
		RegisterDecode(audec,codec_type);
		ret = pthread_create(&tid, NULL, (void *)adec_armdec_loop, (void *)audec);
    }
    if (ret != 0) {
        adec_print("Create adec main thread failed!\n");
        return ret;
    }
    adec_print("Create adec main thread success! tid = %d\n", tid);
    audec->thread_pid = tid;
    return ret;
}
Exemple #2
0
int audiodec_init(aml_audio_dec_t *audec)
{
    int ret = 0;
    pthread_t    tid;
    char value[PROPERTY_VALUE_MAX]={0};
    unsigned wfd = 0;	
    adec_print("audiodec_init!");
    adec_message_pool_init(audec);
    get_output_func(audec);
    int nCodecType=audec->format;
    set_audio_decoder(audec);
    audec->format_changed_flag=0;
    audec->audio_decoder_enabled  = -1;//default set a invalid value
    audec->mix_lr_channel_enable  = -1;
    audec->VersionNum=-1;
    if(am_getconfig_bool("media.libplayer.wfd"))  {
  	wfd = 1;
   }		
    if (get_audio_decoder() == AUDIO_ARC_DECODER) {
    		audec->adsp_ops.dsp_file_fd = -1;
		ret = amthreadpool_pthread_create(&tid, NULL, (void *)adec_message_loop, (void *)audec);
		pthread_setname_np(tid,"AmadecMsgloop");
    }
    else if(wfd && (nCodecType == ACODEC_FMT_AAC ||nCodecType ==  ACODEC_FMT_WIFIDISPLAY)){
		adec_print("using wfd audio decoder \n");
		ret = amthreadpool_pthread_create(&tid, NULL, (void *)adec_wfddec_msg_loop, (void *)audec);
		audec->audio_decoder_enabled = 0x1;
		pthread_setname_np(tid,"AmadecWFDMsgloop");
    }
    else 
    {
		int codec_type=get_audio_decoder();
		RegisterDecode(audec,codec_type);
		ret = amthreadpool_pthread_create(&tid, NULL, (void *)adec_armdec_loop, (void *)audec);
		pthread_mutex_init(&audec->thread_mgt.pthread_mutex, NULL);
		pthread_cond_init(&audec->thread_mgt.pthread_cond, NULL);
		audec->thread_mgt.pthread_id = tid;
		pthread_setname_np(tid,"AmadecArmdecLP");
    }
    if (ret != 0) {
        adec_print("Create adec main thread failed!\n");
        return ret;
    }
    adec_print("Create adec main thread success! tid = %d\n", tid);
    audec->thread_pid = tid;
    return ret;
}
int audiodsp_format_update(aml_audio_dec_t *audec)
{
    int m_fmt;
    int ret = -1;
    unsigned long val;
    dsp_operations_t *dsp_ops = &audec->adsp_ops;
	
    if (dsp_ops->dsp_file_fd < 0 || get_audio_decoder()!=AUDIO_ARC_DECODER) {
        return ret;
    }
	
    ret=0;
    if(1/*audiodsp_get_format_changed_flag()*/)
    {
        ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_CHANNELS_NUM, &val);
        if (val != (unsigned long) - 1) {
            if( audec->channels != val){
                //adec_print("dsp_format_update: pre_channels=%d  cur_channels=%d\n", audec->channels,val);
                audec->channels = val;
                ret=1;
            }
        }

         ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_SAMPLERATE, &val);
         if (val != (unsigned long) - 1) {
            if(audec->samplerate != val){
                //adec_print("dsp_format_update: pre_samplerate=%d  cur_samplerate=%d\n", audec->samplerate,val);
                audec->samplerate = val;
                ret=2;
            }
         }
         #if 1
         ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_BITS_PER_SAMPLE, &val);
         if (val != (unsigned long) - 1) {
            if(audec->data_width != val){
                //adec_print("dsp_format_update: pre_data_width=%d  cur_data_width=%d\n", audec->data_width,val);
                audec->data_width = val;
                ret=3;
            }
        }
        #endif
		//audiodsp_set_format_changed_flag(0);        
        if (am_getconfig_bool("media.libplayer.wfd")) {
	    ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_PCM_LEVEL, &val);
            if (ret == 0) {
                //adec_print("pcm level == 0x%x\n", val);
                if ((val < 0x1000) && (1==audiodsp_get_pcm_resample_enable())) {
                //    adec_print("disable pcm down resample");
                //    audiodsp_set_pcm_resample_enable(0);
                }
            } 
        }
    }
    if(ret>0){
        audec->format_changed_flag=ret;
        adec_print("dsp_format_update: audec->format_changed_flag = %d \n", audec->format_changed_flag); 
    }
    return ret;
}
int audiodec_init(aml_audio_dec_t *audec)
{
    int ret = 0;
    int res = 0;	
    pthread_t    tid;
	char value[PROPERTY_VALUE_MAX]={0};
    adec_print("audiodec_init!\n");
    adec_message_pool_init(audec);
    get_output_func(audec);
    int nCodecType=audec->format;
#ifdef ANDROID
    set_audio_decoder(audec);
#else
    set_linux_audio_decoder(audec);

#endif
    audec->format_changed_flag=0;
		
    if (get_audio_decoder() == AUDIO_ARC_DECODER) {
    		audec->adsp_ops.dsp_file_fd = -1;
		ret = pthread_create(&tid, NULL, (void *)adec_message_loop, (void *)audec);
		//pthread_setname_np(tid,"AmadecMsgloop");
    }
    else 
    {   
        int codec_type=get_audio_decoder();
        res=RegisterDecode(audec,codec_type);
        if(!res){ 		
        ret = pthread_create(&tid, NULL, (void *)adec_armdec_loop, (void *)audec);
        //pthread_setname_np(tid,"AmadecArmdecLP");
        }else{
        adec_print("no arm decoding lib find,so change to arc dsp decoding\n");
        audec->adsp_ops.dsp_file_fd = -1;
        audec->adec_ops=NULL;
        ret = pthread_create(&tid, NULL, (void *)adec_message_loop, (void *)audec);
        //pthread_setname_np(tid,"AmadecMsgloop");
	}   
    }
    if (ret != 0) {
        adec_print("Create adec main thread failed!\n");
        return ret;
    }
    adec_print("Create adec main thread success! tid = %d\n", tid);
    audec->thread_pid = tid;
    return ret;
}
int audiodsp_format_update(aml_audio_dec_t *audec)
{
    int m_fmt;
    int ret = -1;
    unsigned long val;
    dsp_operations_t *dsp_ops = &audec->adsp_ops;
	
    if (dsp_ops->dsp_file_fd < 0 || get_audio_decoder()!=AUDIO_ARC_DECODER) {
        return ret;
    }
	
	ret=0;
	if(1/*audiodsp_get_format_changed_flag()*/)
	{
         ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_CHANNELS_NUM, &val);
         if (val != (unsigned long) - 1) {
		    if( audec->channels != val){
			   //adec_print("dsp_format_update: pre_channels=%d  cur_channels=%d\n", audec->channels,val);
               audec->channels = val;
		       ret=1;
		    }
         }

         ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_SAMPLERATE, &val);
         if (val != (unsigned long) - 1) {
		     if(audec->samplerate != val){
			    //adec_print("dsp_format_update: pre_samplerate=%d  cur_samplerate=%d\n", audec->samplerate,val);
                audec->samplerate = val;
		        ret=2;
		     }
         }
         #if 1
         ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_BITS_PER_SAMPLE, &val);
         if (val != (unsigned long) - 1) {
		     if(audec->data_width != val){
		        //adec_print("dsp_format_update: pre_data_width=%d  cur_data_width=%d\n", audec->data_width,val);
                audec->data_width = val;
		        ret=3;
		     }
         }
		 #endif
		//audiodsp_set_format_changed_flag(0);
	}
	if(ret>0){
	    audec->format_changed_flag=ret;
	    adec_print("dsp_format_update: audec->format_changed_flag = %d \n", audec->format_changed_flag); 
	}
    return ret;
}
static void *audio_decoder_loop (void *stream_gen) {

  buf_element_t   *buf;
  xine_stream_t   *stream = (xine_stream_t *) stream_gen;
  int              running = 1;
  int              prof_audio_decode = -1;
  uint32_t         buftype_unknown = 0;

  if (prof_audio_decode == -1)
    prof_audio_decode = xine_profiler_allocate_slot ("audio decoder/output");

  while (running) {

#ifdef LOG
    printf ("audio_loop: waiting for package...\n");  
#endif

    buf = stream->audio_fifo->get (stream->audio_fifo);

    
#ifdef LOG
    printf ("audio_loop: got package pts = %lld, type = %08x\n", 
	    buf->pts, buf->type); 
#endif    

    extra_info_merge( stream->audio_decoder_extra_info, buf->extra_info );
    stream->audio_decoder_extra_info->seek_count = stream->video_seek_count;
      
    /* check for a new port to use */
    if (stream->next_audio_port) {
      uint32_t bits, rate;
      int mode;
      
      /* noone is allowed to modify the next port from now on */
      pthread_mutex_lock(&stream->next_audio_port_lock);
      if (stream->audio_out->status(stream->audio_out, stream, &bits, &rate, &mode)) {
        /* register our stream at the new output port */
        stream->next_audio_port->open(stream->next_audio_port, stream, bits, rate, mode);
        stream->audio_out->close(stream->audio_out, stream);
      }
      stream->audio_out = stream->next_audio_port;
      stream->next_audio_port = NULL;
      pthread_mutex_unlock(&stream->next_audio_port_lock);
      pthread_cond_broadcast(&stream->next_audio_port_wired);
    }

    switch (buf->type) {
      
    case BUF_CONTROL_HEADERS_DONE:
      pthread_mutex_lock (&stream->counter_lock);
      stream->header_count_audio++;
      pthread_cond_broadcast (&stream->counter_changed);
      pthread_mutex_unlock (&stream->counter_lock);
      break;

    case BUF_CONTROL_START:

#ifdef LOG
      printf ("audio_decoder: start\n");
#endif

      if (stream->audio_decoder_plugin) {

#ifdef LOG
	printf ("audio_decoder: close old decoder\n");
#endif	

	free_audio_decoder (stream, stream->audio_decoder_plugin);
	stream->audio_decoder_plugin = NULL;
	stream->audio_track_map_entries = 0;
	stream->audio_type = 0;
      }
      
      stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
      
      buftype_unknown = 0;
      break;
      
    case BUF_CONTROL_END:

      /* wait for video to reach this marker, if necessary */
      
      pthread_mutex_lock (&stream->counter_lock);

      stream->finished_count_audio++;

#ifdef LOG
      printf ("audio_decoder: reached end marker # %d\n", 
	      stream->finished_count_audio);
#endif

      pthread_cond_broadcast (&stream->counter_changed);

      while (stream->finished_count_video < stream->finished_count_audio) {
        struct timeval tv;
        struct timespec ts;
        gettimeofday(&tv, NULL);
        ts.tv_sec  = tv.tv_sec + 1;
        ts.tv_nsec = tv.tv_usec * 1000;
        /* use timedwait to workaround buggy pthread broadcast implementations */
        pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
      }
          
      pthread_mutex_unlock (&stream->counter_lock);

      stream->audio_channel_auto = -1;

      break;
      
    case BUF_CONTROL_QUIT:
      if (stream->audio_decoder_plugin) {
	free_audio_decoder (stream, stream->audio_decoder_plugin);
	stream->audio_decoder_plugin = NULL;
	stream->audio_track_map_entries = 0;
	stream->audio_type = 0;
      }
      running = 0;
      break;

    case BUF_CONTROL_NOP:
      break;

    case BUF_CONTROL_RESET_DECODER:
#ifdef LOG
      printf ("audio_decoder: reset\n");
#endif
      extra_info_reset( stream->audio_decoder_extra_info );
      if (stream->audio_decoder_plugin)
        stream->audio_decoder_plugin->reset (stream->audio_decoder_plugin);
      break;
          
    case BUF_CONTROL_DISCONTINUITY:
      if (stream->audio_decoder_plugin)
        stream->audio_decoder_plugin->discontinuity (stream->audio_decoder_plugin);
      stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_RELATIVE, buf->disc_off);
      break;

    case BUF_CONTROL_NEWPTS:
      if (stream->audio_decoder_plugin)
        stream->audio_decoder_plugin->discontinuity (stream->audio_decoder_plugin);
      if (buf->decoder_flags && BUF_FLAG_SEEK) {
        stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSEEK, buf->disc_off);
      } else {
        stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_ABSOLUTE, buf->disc_off);
      }
      break;

    case BUF_CONTROL_AUDIO_CHANNEL:
      {
	if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG)
	  printf ("audio_decoder: suggested switching to stream_id %02x\n",
		  buf->decoder_info[0]);
	stream->audio_channel_auto = buf->decoder_info[0] & 0xff;
      }
      break;

    default:

      if (stream->stream_info[XINE_STREAM_INFO_IGNORE_AUDIO])
        break;

      xine_profiler_start_count (prof_audio_decode);

      if ( (buf->type & 0xFF000000) == BUF_AUDIO_BASE ) {
	
	uint32_t audio_type = 0;
	int      i,j;

	/*
        printf("audio_decoder: buf_type=%08x auto=%08x user=%08x\n",
	       buf->type, 
	       stream->audio_channel_auto,
	       stream->audio_channel_user);
	       */

        /* update track map */
        
        i = 0;
        while ( (i<stream->audio_track_map_entries) && (stream->audio_track_map[i]<buf->type) ) 
          i++;
        
        if ( (i==stream->audio_track_map_entries) 
	     || (stream->audio_track_map[i] != buf->type) ) {
          
          j = stream->audio_track_map_entries;

          if (j >= 50)
            break;

          while (j>i) {
            stream->audio_track_map[j] = stream->audio_track_map[j-1];
            j--;
          }
          stream->audio_track_map[i] = buf->type;
          stream->audio_track_map_entries++;
        }

	/* find out which audio type to decode */

#ifdef LOG
	printf ("audio_decoder: audio_channel_user = %d, map[0]=%08x\n",
		stream->audio_channel_user,
		stream->audio_track_map[0]);
#endif

	if (stream->audio_channel_user > -2) {

	  if (stream->audio_channel_user == -1) {

	    /* auto */

#ifdef LOG
	    printf ("audio_decoder: audio_channel_auto = %d\n",
		    stream->audio_channel_auto);
#endif

	    if (stream->audio_channel_auto>=0) {
 
	      if ((buf->type & 0xFF) == stream->audio_channel_auto) {
		audio_type = buf->type;
	      } else
		audio_type = -1;

	    } else
	      audio_type = stream->audio_track_map[0];

	  } else {
	    if (stream->audio_channel_user <= stream->audio_track_map_entries)
	      audio_type = stream->audio_track_map[stream->audio_channel_user];
	    else
	      audio_type = -1;
	  }

	  /* now, decode stream buffer if it's the right audio type */
	  
	  if (buf->type == audio_type) {
	    
	    int streamtype = (buf->type>>16) & 0xFF;

	    /* close old decoder of audio type has changed */
        
            if( buf->type != buftype_unknown && 
                (stream->audio_decoder_streamtype != streamtype ||
                !stream->audio_decoder_plugin) ) {
              
              if (stream->audio_decoder_plugin) {
                free_audio_decoder (stream, stream->audio_decoder_plugin);
              }
              
              stream->audio_decoder_streamtype = streamtype;
              stream->audio_decoder_plugin = get_audio_decoder (stream, streamtype);
              
              stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED] = 
                (stream->audio_decoder_plugin != NULL);
            }
	    
	    if (audio_type != stream->audio_type) {
	      
	      if (stream->audio_decoder_plugin) {
		xine_event_t event;

		stream->audio_type = audio_type;

		event.type         = XINE_EVENT_UI_CHANNELS_CHANGED;
		event.data_length  = 0;
		xine_event_send(stream, &event);
	      }
	    }
	    
	    /* finally - decode data */
	    
	    if (stream->audio_decoder_plugin) 
	      stream->audio_decoder_plugin->decode_data (stream->audio_decoder_plugin, buf);
       
	    if (buf->type != buftype_unknown && 
	        !stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED]) {
	      xine_log (stream->xine, XINE_LOG_MSG, 
			"audio_decoder: no plugin available to handle '%s'\n",
		        buf_audio_name( buf->type ) );
              
              if( !stream->meta_info[XINE_META_INFO_AUDIOCODEC] )
                stream->meta_info[XINE_META_INFO_AUDIOCODEC] 
                  = strdup (buf_audio_name( buf->type ));
                
	      buftype_unknown = buf->type;

	      /* fatal error - dispose plugin */       
	      if (stream->audio_decoder_plugin) {
	        free_audio_decoder (stream, stream->audio_decoder_plugin);
	        stream->audio_decoder_plugin = NULL;
	      }
	    }
	  }
	} 
      } else if( buf->type != buftype_unknown ) {