int ffmpeg_init(void)
{
    if (basic_init > 0) {
        return 0;
    }
    basic_init++;
    av_register_all();
    av_lockmgr_register(ffmpeg_lock);
    url_set_interrupt_cb(ffmpeg_interrupt_callback);
    kill_item_list.max_items = MAX_PLAYER_THREADS;
    kill_item_list.item_ext_buf_size = 0;
    kill_item_list.muti_threads_access = 1;
    kill_item_list.reject_same_item_data = 1;
    itemlist_init(&kill_item_list);
    return 0;
}
Пример #2
0
static int SetupAvioCb(vlc_object_t *access)
{
    static vlc_mutex_t avio_lock = VLC_STATIC_MUTEX;
    vlc_mutex_lock(&avio_lock);
    assert(!access != !current_access);
    if (access && current_access) {
        vlc_mutex_unlock(&avio_lock);
        return VLC_EGENERIC;
    }
    url_set_interrupt_cb(access ? UrlInterruptCallbackSingle : NULL);

    current_access = access;

    vlc_mutex_unlock(&avio_lock);

    return VLC_SUCCESS;
}
Пример #3
0
int video_init( void ) {
    avcodec_register_all();
    av_register_all();

    conv_frame = avcodec_alloc_frame();

    if( !conv_frame ) {
        fprintf( stderr, "Warning: Couldn't allocate video conversion frame\n" );
        return -1;
    }

    packet_queue_init( &audio_queue );
    frame_queue_init( &video_queue );

    url_set_interrupt_cb( video_stopped );

    return 0;
}
Пример #4
0
int decode_thread(void *arg) {

  VideoState *is = (VideoState *)arg;
  AVFormatContext *pFormatCtx;
  AVPacket pkt1, *packet = &pkt1;

  int video_index = -1;
  int audio_index = -1;
  int i;

  is->videoStream=-1;
  is->audioStream=-1;

  global_video_state = is;
  // will interrupt blocking functions if we quit!
  url_set_interrupt_cb(decode_interrupt_cb);

  // Open video file
  if(av_open_input_file(&pFormatCtx, is->filename, NULL, 0, NULL)!=0)
    return -1; // Couldn't open file

  is->pFormatCtx = pFormatCtx;
  
  // Retrieve stream information
  if(av_find_stream_info(pFormatCtx)<0)
    return -1; // Couldn't find stream information
  
  // Dump information about file onto standard error
  dump_format(pFormatCtx, 0, is->filename, 0);
  
  // Find the first video stream
  for(i=0; i<pFormatCtx->nb_streams; i++) {
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO &&
       video_index < 0) {
      video_index=i;
    }
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO &&
       audio_index < 0) {
      audio_index=i;
    }
  }
  if(audio_index >= 0) {
    stream_component_open(is, audio_index);
  }
  if(video_index >= 0) {
    stream_component_open(is, video_index);
  }   

  if(is->videoStream < 0 || is->audioStream < 0) {
    fprintf(stderr, "%s: could not open codecs\n", is->filename);
    goto fail;
  }

  // main decode loop

  for(;;) {
    if(is->quit) {
      break;
    }
    // seek stuff goes here
    if(is->seek_req) {
      int stream_index= -1;
      int64_t seek_target = is->seek_pos;

      if     (is->videoStream >= 0) stream_index = is->videoStream;
      else if(is->audioStream >= 0) stream_index = is->audioStream;

      if(stream_index>=0){
	seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, pFormatCtx->streams[stream_index]->time_base);
      }
      if(!av_seek_frame(is->pFormatCtx, stream_index, seek_target, is->seek_flags)) {
	fprintf(stderr, "%s: error while seeking\n", is->pFormatCtx->filename);
      } else {
	if(is->audioStream >= 0) {
	  packet_queue_flush(&is->audioq);
	  packet_queue_put(&is->audioq, &flush_pkt);
	}
	if(is->videoStream >= 0) {
	  packet_queue_flush(&is->videoq);
	  packet_queue_put(&is->videoq, &flush_pkt);
	}
      }
      is->seek_req = 0;
    }

    if(is->audioq.size > MAX_AUDIOQ_SIZE ||
       is->videoq.size > MAX_VIDEOQ_SIZE) {
      SDL_Delay(10);
      continue;
    }
    if(av_read_frame(is->pFormatCtx, packet) < 0) {
      if(url_ferror(&pFormatCtx->pb) == 0) {
	SDL_Delay(100); /* no error; wait for user input */
	continue;
      } else {
	break;
      }
    }
    // Is this a packet from the video stream?
    if(packet->stream_index == is->videoStream) {
      packet_queue_put(&is->videoq, packet);
    } else if(packet->stream_index == is->audioStream) {
      packet_queue_put(&is->audioq, packet);
    } else {
      av_free_packet(packet);
    }
  }
  /* all done - wait for it */
  while(!is->quit) {
    SDL_Delay(100);
  }
 fail:
  {
    SDL_Event event;
    event.type = FF_QUIT_EVENT;
    event.user.data1 = is;
    SDL_PushEvent(&event);
  }
  return 0;
}
Пример #5
0
bool VideoLayer::open(const char *file) {
  AVCodecContext *enc; // tmp
  int err=0;
  video_index=-1;
  func("VideoLayer::open(%s)",file);


  AVInputFormat *av_input_format = NULL;
  AVFormatParameters avp, *av_format_par = NULL;
  av_format_par = &avp;
  memset (av_format_par, 0, sizeof (*av_format_par));
  av_format_par->width=0;
  av_format_par->width=0;
  av_format_par->time_base  = (AVRational){1, 25};
  av_format_par->pix_fmt=PIX_FMT_RGB32;

  /* handle firewire cam */
  if( strncasecmp (file, "/dev/ieee1394/",14) == 0) {
    notice ("VideoLayer::found dv1394 device!\n");
    grab_dv = true;
    av_input_format = av_find_input_format("dv1394");

    /** shit XXX */
    av_format_par -> width             = 720;
    av_format_par -> height            = 576;
#if LIBAVCODEC_BUILD  >=     4754
    av_format_par -> time_base.num   = 25;
    av_format_par -> time_base.den   = 1;
#else
    av_format_par -> frame_rate      = 25;
    av_format_par -> frame_rate_base = 1;
#endif
    // field removed in recent ffmpeg API (todo: check LIBAVCODEC_BUILD)
    //    av_format_par -> device          = file;
    av_format_par -> standard        = "pal";
    //	av_format_par->channel=0;
    file="";
  }

  /** 
   * The callback is called in blocking functions to test regulary if
   * asynchronous interruption is needed. -EINTR is returned in this
   * case by the interrupted function. 'NULL' means no interrupt
   * callback is given.  
   */
  url_set_interrupt_cb(NULL);


  /**
   * Open media with libavformat
   */
  err = av_open_input_file (&avformat_context, file, av_input_format, 0, av_format_par);
  if (err < 0) {
    error("VideoLayer :: open(%s) - can't open. Error %d", file, err);
    return false;
  }
  func("VideoLayer :: file opened with success");

  /**
   * Find info with libavformat
   */
  err = av_find_stream_info(avformat_context);
  if (err < 0) {
    error("VideoLayer :: could not find stream info");
    return false;
  }
  func("VideoLayer :: stream info found");
  /* now we can begin to play (RTSP stream only) */
  av_read_play(avformat_context);

  /**
   * Open codec if we find a video stream
   */
  unsigned int i;
  for(i=0; i < avformat_context -> nb_streams; i++) {
    avformat_stream = avformat_context -> streams[i];
    enc = avformat_stream->codec;
    if(enc == NULL) error("%s: AVCodecContext is NULL", __PRETTY_FUNCTION__);

    switch(enc->codec_type) {

    /**
     * Here we look for a video stream
     */
//    case CODEC_TYPE_VIDEO: // old FFMPEG
    case AVMEDIA_TYPE_VIDEO:
      //      enc->flags |= CODEC_FLAG_LOOP_FILTER;
      video_index = i;
      video_codec_ctx = enc;

      video_codec = avcodec_find_decoder (video_codec_ctx -> codec_id);
      if(video_codec==NULL) {
	error("VideoLayer :: Could not find a suitable codec");
	return false;
      }
      
      if (avcodec_open(video_codec_ctx, video_codec) < 0) {
	error("VideoLayer :: Could not open codec");
	return false;
	
      } else { // correctly opened
	
#if LIBAVCODEC_BUILD  >=     4754
	if(avformat_stream->r_frame_rate.den && avformat_stream->r_frame_rate.num)
	  frame_rate = av_q2d(avformat_stream->r_frame_rate);
	else
	  frame_rate = enc -> time_base.den / enc -> time_base.num;

	AVRational rational = enc -> time_base;
	func ("VideoLayer :: frame_rate den: %d", enc -> time_base .den);
	func ("VideoLayer :: frame_rate num: %d", enc -> time_base .num);
#else
	frame_rate = video_codec_ctx->frame_rate / 
	  video_codec_ctx->frame_rate_base;
#endif
	// set the layer fps
	fps.set(frame_rate);
	/* this saves only file without full path! */
	set_filename (file);

	act ("%s (codec: %s) has resolution %dx%d and framerate %f",
	     get_filename(), video_codec->name,
	     video_codec_ctx->width, video_codec_ctx->height, frame_rate);

	break;
      }
      
      break; // //////////////// end of video section

    case AVMEDIA_TYPE_AUDIO:
      audio_index = i;
      audio_codec_ctx = enc;
      func ("VideoLayer :: audio id=%i", audio_index);

      audio_codec = avcodec_find_decoder(audio_codec_ctx -> codec_id);
      if(audio_codec==NULL) {
	error("VideoLayer :: Could not find a suitable codec for audio");
	return false;
      }
      if (avcodec_open(audio_codec_ctx, audio_codec) < 0) {
	error("VideoLayer :: Could not open codec for audio");
	return false;
	
      } else { // correctly opened
	//AVCODEC_MAX_AUDIO_FRAME_SIZE = 192000
	audio_buf = (uint8_t*)calloc(AVCODEC_MAX_AUDIO_FRAME_SIZE, sizeof(int16_t));
	
	audio_channels = audio_codec_ctx->channels;
	audio_samplerate = audio_codec_ctx->sample_rate;

	audio_float_buf = (float*) malloc(audio_channels * AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(float));

	act("VideoLayer :: audio stream (codec: %s) has %u channels at samplerate %u",
	    audio_codec->name, audio_channels, audio_samplerate);

      }
      break; // /////// end of audio section


    case AVMEDIA_TYPE_SUBTITLE:
      act("stream has also subtitles");
      break;
    case AVMEDIA_TYPE_ATTACHMENT:
      act("stream has also attachment");
      break;
    case AVMEDIA_TYPE_DATA:
      act("stream has also a data carrier");
      break;
    default:
      act("stream has also an unknown codec stream");
      break;
    }

  } // done looking for streams

  if (video_index < 0) {
    error("VideoLayer :: Could not open codec");
    return false;
  }

  full_filename = strdup (file);

  geo.init(video_codec_ctx->width, video_codec_ctx->height, 32);
  func("VideoLayer :: w[%u] h[%u] size[%u]", geo.w, geo.h, geo.bytesize);
  func("VideoLayer :: frame_rate[%f]",frame_rate);

  // initialize picture
  if( new_picture(rgba_picture) < 0) {
    error("VideoLayer::error allocating picture");
    return false;
  }

#ifdef WITH_SWSCALE
  img_convert_ctx =
    sws_getContext(geo.w, geo.h, video_codec_ctx->pix_fmt, geo.w, geo.h,
		   PIX_FMT_RGB32, SWS_BICUBIC, 
		   NULL, NULL, NULL);
#endif

  // initialize frame fifo 
  if(  new_fifo() < 0) {
    error("VideoLayer::error allocating fifo");
    return false;
  }

  // feed() function is called 25 times for second so we must correct the speed
  // TODO user should be able to select the clock speed
  if (play_speed != 25) {
    play_speed -= (25 / frame_rate);
    //	play_speed -= play_speed << 1;
    if ( frame_rate ==1)
      play_speed = 0;
  }
  func ("VideoLayer :: play_speed: %d",play_speed);

  opened = true;

  type = VIDEOLAYER;
  
  return true;
}
Пример #6
0
int decode_thread( void *thread_arg )
{
  VideoState *is = (VideoState *) thread_arg;
  AVFormatContext *pFormatCtx;
  AVPacket pkt1, *packet = &pkt1;
  //global_video_state = is;
  url_set_interrupt_cb(decode_interrupt_cb); // will interrupt blocking functions if we quit!

//  is->filename[0] = *"./foo.mkv";
  strcpy(is->filename, "./foo.mkv");

  int i;
  //AVCodecContext *pCodecCtx;
  //AVCodecContext *aCodecCtx;

  // Open video file
  if( av_open_input_file(&pFormatCtx, is->filename, NULL, 0, NULL) != 0 )
    return -1; // Couldn't open file
  is->pFormatCtx = pFormatCtx;

  // Retrieve stream information
  if(av_find_stream_info(pFormatCtx)<0)
    return -1; // Couldn't find stream information

  // Dump information about file onto standard error
  //dump_format(pFormatCtx, 0, is->filename, 0);

  // Find the video stream and audio stream
  int videoStream = -1;
  int audioStream = -1;
  is->videoStream = -1;
  is->audioStream = -1;
  for( i=0; i<pFormatCtx->nb_streams; i++ )
  {
    if( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO ) {
      videoStream = i;
    }
    if( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audioStream < 0 ) {
      audioStream = i;
    }
  }

  if(videoStream == -1)
    return -1; // Didn't find a video stream
  if(audioStream == -1)
    printf( "No audio stream\n" );
  else
    stream_component_open( is, audioStream );

  stream_component_open( is, videoStream );

  if(is->videoStream < 0 ) {
    fprintf(stderr, "%s: could not open codecs\n", is->filename);
    goto fail;
  } 

  // Decode loop
  for(;;) {
    if(is->quit) {
      break;
    }
    if(is->audioq.size > MAX_AUDIOQ_SIZE ||
       is->videoq.size > MAX_VIDEOQ_SIZE) {
      SDL_Delay(10);
      continue;
    }
/*
    if( av_read_frame(is->pFormatCtx, packet) < 0 ) {
      if( url_ferror((ByteIOContext *)&pFormatCtx->pb) == 0 ) {
        SDL_Delay(100); // no error; wait for user input
        continue;
      } else {
        break;
      }
    }

    // Queue the packets into the right queue
    if(packet->stream_index == is->videoStream) {
      packet_queue_put(&is->videoq, packet);
    } else if(packet->stream_index == is->audioStream) {
      packet_queue_put(&is->audioq, packet);
    } else {
      av_free_packet(packet);
    }
*/
  }

  while(!is->quit) {
    SDL_Delay(100);
  }

 fail:
  if(1){
    SDL_Event event;
    event.type = FF_QUIT_EVENT;
    event.user.data1 = is;
    SDL_PushEvent(&event);
  }
  return 0;

} // End decode_thread()