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; }
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; }
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; }
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; }
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; }
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()