int set_data_source_l(State **ps, const char* path) { printf("set_data_source\n"); int audio_index = -1; int video_index = -1; int i; State *state = *ps; printf("Path: %s\n", path); AVDictionary *options = NULL; av_dict_set(&options, "icy", "1", 0); av_dict_set(&options, "user-agent", "FFmpegMediaMetadataRetriever", 0); if (state->headers) { av_dict_set(&options, "headers", state->headers, 0); } if (state->offset > 0) { state->pFormatCtx = avformat_alloc_context(); state->pFormatCtx->skip_initial_bytes = state->offset; } if (avformat_open_input(&state->pFormatCtx, path, NULL, &options) != 0) { printf("Metadata could not be retrieved\n"); *ps = NULL; return FAILURE; } if (avformat_find_stream_info(state->pFormatCtx, NULL) < 0) { printf("Metadata could not be retrieved\n"); avformat_close_input(&state->pFormatCtx); *ps = NULL; return FAILURE; } set_duration(state->pFormatCtx); set_shoutcast_metadata(state->pFormatCtx); //av_dump_format(state->pFormatCtx, 0, path, 0); // Find the first audio and video stream for (i = 0; i < state->pFormatCtx->nb_streams; i++) { if (state->pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_index < 0) { video_index = i; } if (state->pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_index < 0) { audio_index = i; } set_codec(state->pFormatCtx, i); } if (audio_index >= 0) { stream_component_open(state, audio_index); } if (video_index >= 0) { stream_component_open(state, video_index); } /*if(state->video_stream < 0 || state->audio_stream < 0) { avformat_close_input(&state->pFormatCtx); *ps = NULL; return FAILURE; }*/ set_rotation(state->pFormatCtx, state->audio_st, state->video_st); set_framerate(state->pFormatCtx, state->audio_st, state->video_st); set_filesize(state->pFormatCtx); set_chapter_count(state->pFormatCtx); /*printf("Found metadata\n"); AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get(state->pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { printf("Key %s: \n", tag->key); printf("Value %s: \n", tag->value); }*/ *ps = state; return SUCCESS; }
int decode_thread(void *arg) { VideoState *is = (VideoState *)arg; AVPacket pkt1, *packet = &pkt1; AVDictionary *io_dict = NULL; AVIOInterruptCB callback; int video_index = -1; int audio_index = -1; int i; int ret; int eof = 0; is->videoStream=-1; is->audioStream=-1; AVDictionary *options = NULL; av_dict_set(&options, "icy", "1", 0); av_dict_set(&options, "user-agent", "FFmpegMediaPlayer", 0); if (is->headers) { av_dict_set(&options, "headers", is->headers, 0); } if (is->offset > 0) { is->pFormatCtx = avformat_alloc_context(); is->pFormatCtx->skip_initial_bytes = is->offset; //is->pFormatCtx->iformat = av_find_input_format("mp3"); } // will interrupt blocking functions if we quit! callback.callback = decode_interrupt_cb; callback.opaque = is; if (avio_open2(&is->io_context, is->filename, 0, &callback, &io_dict)) { fprintf(stderr, "Unable to open I/O for %s\n", is->filename); return -1; } // Open video file if(avformat_open_input(&is->pFormatCtx, is->filename, NULL, &options)!=0) return -1; // Couldn't open file // Retrieve stream information if(avformat_find_stream_info(is->pFormatCtx, NULL)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(is->pFormatCtx, 0, is->filename, 0); // Find the first video stream for(i=0; i<is->pFormatCtx->nb_streams; i++) { if(is->pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO && video_index < 0) { video_index=i; } if(is->pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO && audio_index < 0) { audio_index=i; } set_codec(is->pFormatCtx, 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) { //if(is->videoStream < 0 || is->audioStream < 0) { fprintf(stderr, "%s: could not open codecs\n", is->filename); notify(is, MEDIA_ERROR, 0, 0); return 0; } set_rotation(is->pFormatCtx, is->audio_st, is->video_st); set_framerate(is->pFormatCtx, is->audio_st, is->video_st); set_filesize(is->pFormatCtx); set_chapter_count(is->pFormatCtx); // main decode loop for(;;) { if(is->quit) { break; } /*if (is->paused != is->last_paused) { is->last_paused = is->paused; if (is->paused) is->read_pause_return = av_read_pause(is->pFormatCtx); else av_read_play(is->pFormatCtx); }*/ // seek stuff goes here if(is->seek_req) { int64_t seek_target = is->seek_pos; int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN; int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX; int ret = avformat_seek_file(is->pFormatCtx, -1, seek_min, seek_target, seek_max, is->seek_flags); if(ret < 0) { fprintf(stderr, "%s: error while seeking\n", is->pFormatCtx->filename); } else { if(is->audioStream >= 0) { packet_queue_flush(&is->audioq); packet_queue_put(is, &is->audioq, &is->flush_pkt); } if(is->videoStream >= 0) { packet_queue_flush(&is->videoq); packet_queue_put(is, &is->videoq, &is->flush_pkt); } notify(is, MEDIA_SEEK_COMPLETE, 0, 0); } is->seek_req = 0; eof = 0; } if (is->audioq.size >= MAX_AUDIOQ_SIZE && !is->prepared) { queueAudioSamples(&is->audio_player, is); notify(is, MEDIA_PREPARED, 0, 0); is->prepared = 1; } if(is->audioq.size > MAX_AUDIOQ_SIZE || is->videoq.size > MAX_VIDEOQ_SIZE) { SDL_Delay(10); continue; } if((ret = av_read_frame(is->pFormatCtx, packet)) < 0) { if (ret == AVERROR_EOF || !is->pFormatCtx->pb->eof_reached) { eof = 1; break; } if(is->pFormatCtx->pb->error == 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, &is->videoq, packet); } else if(packet->stream_index == is->audioStream) { packet_queue_put(is, &is->audioq, packet); } else { av_free_packet(packet); } if (eof) { break; } } if (eof) { notify(is, MEDIA_PLAYBACK_COMPLETE, 0, 0); } return 0; }