return ret;
}
+static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
+{
+ AVPacket pkt1, *pkt = &pkt1;
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->stream_index = stream_index;
+ return packet_queue_put(q, pkt);
+}
+
/* packet queue handling */
static void packet_queue_init(PacketQueue *q)
{
}
}
+static void free_picture(VideoPicture *vp)
+{
+ if (vp->bmp) {
+ SDL_FreeYUVOverlay(vp->bmp);
+ vp->bmp = NULL;
+ }
+}
+
static void free_subpicture(SubPicture *sp)
{
avsubtitle_free(&sp->sub);
static void stream_close(VideoState *is)
{
- VideoPicture *vp;
int i;
/* XXX: use a special url_shutdown call to abort parse cleanly */
is->abort_request = 1;
packet_queue_destroy(&is->subtitleq);
/* free all pictures */
- for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
- vp = &is->pictq[i];
- if (vp->bmp) {
- SDL_FreeYUVOverlay(vp->bmp);
- vp->bmp = NULL;
- }
- }
+ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
+ free_picture(&is->pictq[i]);
for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
free_subpicture(&is->subpq[i]);
SDL_DestroyMutex(is->pictq_mutex);
vp = &is->pictq[is->pictq_windex];
- if (vp->bmp)
- SDL_FreeYUVOverlay(vp->bmp);
+ free_picture(vp);
video_open(is, 0, vp);
!isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
clockdiff + ptsdiff - is->frame_last_filter_delay < 0 &&
is->videoq.nb_packets) {
- is->frame_last_dropped_pos = pkt->pos;
+ is->frame_last_dropped_pos = av_frame_get_pkt_pos(frame);
is->frame_last_dropped_pts = dpts;
is->frame_last_dropped_serial = *serial;
is->frame_drops_early++;
int64_t channel_layouts[2] = { 0, -1 };
int channels[2] = { 0, -1 };
AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
+ char aresample_swr_opts[512] = "";
+ AVDictionaryEntry *e = NULL;
char asrc_args[256];
int ret;
if (!(is->agraph = avfilter_graph_alloc()))
return AVERROR(ENOMEM);
+ while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
+ av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
+ if (strlen(aresample_swr_opts))
+ aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
+ av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
+
ret = snprintf(asrc_args, sizeof(asrc_args),
"sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
}
#else
pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(is->video_st->time_base);
- ret = queue_picture(is, frame, pts, pkt.pos, serial);
+ ret = queue_picture(is, frame, pts, av_frame_get_pkt_pos(frame), serial);
av_frame_unref(frame);
#endif
if ((ret = av_copy_packet(©, &is->video_st->attached_pic)) < 0)
goto fail;
packet_queue_put(&is->videoq, ©);
+ packet_queue_put_nullpacket(&is->videoq, is->video_stream);
}
is->queue_attachments_req = 0;
}
}
}
if (eof) {
- if (is->video_stream >= 0) {
- av_init_packet(pkt);
- pkt->data = NULL;
- pkt->size = 0;
- pkt->stream_index = is->video_stream;
- packet_queue_put(&is->videoq, pkt);
- }
- if (is->audio_stream >= 0) {
- av_init_packet(pkt);
- pkt->data = NULL;
- pkt->size = 0;
- pkt->stream_index = is->audio_stream;
- packet_queue_put(&is->audioq, pkt);
- }
+ if (is->video_stream >= 0)
+ packet_queue_put_nullpacket(&is->videoq, is->video_stream);
+ if (is->audio_stream >= 0)
+ packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
SDL_Delay(10);
eof=0;
continue;
int start_index, stream_index;
int old_index;
AVStream *st;
+ AVProgram *p = NULL;
+ int nb_streams = is->ic->nb_streams;
if (codec_type == AVMEDIA_TYPE_VIDEO) {
start_index = is->last_video_stream;
old_index = is->subtitle_stream;
}
stream_index = start_index;
+
+ if (codec_type != AVMEDIA_TYPE_VIDEO && is->video_stream != -1) {
+ p = av_find_program_from_stream(ic, NULL, is->video_stream);
+ if (p) {
+ nb_streams = p->nb_stream_indexes;
+ for (start_index = 0; start_index < nb_streams; start_index++)
+ if (p->stream_index[start_index] == stream_index)
+ break;
+ if (start_index == nb_streams)
+ start_index = -1;
+ stream_index = start_index;
+ }
+ }
+
for (;;) {
- if (++stream_index >= is->ic->nb_streams)
+ if (++stream_index >= nb_streams)
{
if (codec_type == AVMEDIA_TYPE_SUBTITLE)
{
}
if (stream_index == start_index)
return;
- st = ic->streams[stream_index];
+ st = is->ic->streams[p ? p->stream_index[stream_index] : stream_index];
if (st->codec->codec_type == codec_type) {
/* check that parameters are OK */
switch (codec_type) {
}
}
the_end:
+ if (p && stream_index != -1)
+ stream_index = p->stream_index[stream_index];
stream_component_close(is, old_index);
stream_component_open(is, stream_index);
}
case SDLK_v:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
break;
+ case SDLK_c:
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+ break;
case SDLK_t:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
break;
"q, ESC quit\n"
"f toggle full screen\n"
"p, SPC pause\n"
- "a cycle audio channel\n"
+ "a cycle audio channel in the current program\n"
"v cycle video channel\n"
- "t cycle subtitle channel\n"
+ "t cycle subtitle channel in the current program\n"
+ "c cycle program\n"
"w show audio waves\n"
"s activate frame-step mode\n"
"left/right seek backward/forward 10 seconds\n"