int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size) { MOVMuxContext *mov = s->priv_data; MOVTrack *trk = &mov->tracks[track_index]; AVFormatContext *rtp_ctx = trk->rtp_ctx; uint8_t *buf = NULL; int size; AVIOContext *hintbuf = NULL; AVPacket hint_pkt; int ret = 0, count; if (!rtp_ctx) return AVERROR(ENOENT); if (!rtp_ctx->pb) return AVERROR(ENOMEM); if (sample_data) sample_queue_push(&trk->sample_queue, sample_data, sample_size, sample); else sample_queue_push(&trk->sample_queue, pkt->data, pkt->size, sample); /* Feed the packet to the RTP muxer */ ff_write_chained(rtp_ctx, 0, pkt, s); /* Fetch the output from the RTP muxer, open a new output buffer * for next time. */ size = avio_close_dyn_buf(rtp_ctx->pb, &buf); if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb, RTP_MAX_PACKET_SIZE)) < 0) goto done; if (size <= 0) goto done; /* Open a buffer for writing the hint */ if ((ret = avio_open_dyn_buf(&hintbuf)) < 0) goto done; av_init_packet(&hint_pkt); count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts); av_freep(&buf); /* Write the hint data into the hint track */ hint_pkt.size = size = avio_close_dyn_buf(hintbuf, &buf); hint_pkt.data = buf; hint_pkt.pts = hint_pkt.dts; hint_pkt.stream_index = track_index; if (pkt->flags & AV_PKT_FLAG_KEY) hint_pkt.flags |= AV_PKT_FLAG_KEY; if (count > 0) ff_mov_write_packet(s, &hint_pkt); done: av_free(buf); sample_queue_retain(&trk->sample_queue); return ret; }
static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; AVStream *st = s->streams[pkt->stream_index]; int64_t end_pts = seg->recording_time * seg->number; int ret, can_split = 1; if (!oc) return AVERROR(EINVAL); if (seg->has_video) { can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->flags & AV_PKT_FLAG_KEY; } if (can_split && av_compare_ts(pkt->pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0) { av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n", pkt->stream_index, pkt->pts); ret = segment_end(oc, seg->individual_header_trailer); if (!ret) ret = segment_start(s, seg->individual_header_trailer); if (ret) goto fail; oc = seg->avf; if (seg->list) { if (seg->list_type == LIST_HLS) { if ((ret = segment_hls_window(s, 0)) < 0) goto fail; } else { avio_printf(seg->pb, "%s\n", oc->filename); avio_flush(seg->pb); if (seg->size && !(seg->number % seg->size)) { ff_format_io_close(s, &seg->pb); if ((ret = s->io_open(s, &seg->pb, seg->list, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } } } } ret = ff_write_chained(oc, pkt->stream_index, pkt, s); fail: if (ret < 0) seg_free_context(seg); return ret; }
static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; fd_set rfds; int n, tcp_fd; struct timeval tv; AVFormatContext *rtpctx; int ret; tcp_fd = url_get_file_handle(rt->rtsp_hd); while (1) { FD_ZERO(&rfds); FD_SET(tcp_fd, &rfds); tv.tv_sec = 0; tv.tv_usec = 0; n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv); if (n <= 0) break; if (FD_ISSET(tcp_fd, &rfds)) { RTSPMessageHeader reply; /* Don't let ff_rtsp_read_reply handle interleaved packets, * since it would block and wait for an RTSP reply on the socket * (which may not be coming any time soon) if it handles * interleaved packets internally. */ ret = ff_rtsp_read_reply(s, &reply, NULL, 1); if (ret < 0) return AVERROR(EPIPE); if (ret == 1) ff_rtsp_skip_packet(s); /* XXX: parse message */ if (rt->state != RTSP_STATE_STREAMING) return AVERROR(EPIPE); } } if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams) return AVERROR_INVALIDDATA; rtsp_st = rt->rtsp_streams[pkt->stream_index]; rtpctx = rtsp_st->transport_priv; ret = ff_write_chained(rtpctx, 0, pkt, s); /* ff_write_chained does all the RTP packetization. If using TCP as * transport, rtpctx->pb is only a dyn_packet_buf that queues up the * packets, so we need to send them out on the TCP connection separately. */ if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) ret = tcp_write_packet(s, rtsp_st); return ret; }
static int sap_write_packet(AVFormatContext *s, AVPacket *pkt) { AVFormatContext *rtpctx; struct SAPState *sap = s->priv_data; int64_t now = av_gettime(); if (!sap->last_time || now - sap->last_time > 5000000) { int ret = ffurl_write(sap->ann_fd, sap->ann, sap->ann_size); /* Don't abort even if we get "Destination unreachable" */ if (ret < 0 && ret != AVERROR(ECONNREFUSED)) return ret; sap->last_time = now; } rtpctx = s->streams[pkt->stream_index]->priv_data; return ff_write_chained(rtpctx, 0, pkt, s); }
static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; int n; struct pollfd p = {ffurl_get_file_handle(rt->rtsp_hd), POLLIN, 0}; AVFormatContext *rtpctx; int ret; while (1) { n = poll(&p, 1, 0); if (n <= 0) break; if (p.revents & POLLIN) { RTSPMessageHeader reply; /* Don't let ff_rtsp_read_reply handle interleaved packets, * since it would block and wait for an RTSP reply on the socket * (which may not be coming any time soon) if it handles * interleaved packets internally. */ ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL); if (ret < 0) return AVERROR(EPIPE); if (ret == 1) ff_rtsp_skip_packet(s); /* XXX: parse message */ if (rt->state != RTSP_STATE_STREAMING) return AVERROR(EPIPE); } } if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams) return AVERROR_INVALIDDATA; rtsp_st = rt->rtsp_streams[pkt->stream_index]; rtpctx = rtsp_st->transport_priv; ret = ff_write_chained(rtpctx, 0, pkt, s); /* ff_write_chained does all the RTP packetization. If using TCP as * transport, rtpctx->pb is only a dyn_packet_buf that queues up the * packets, so we need to send them out on the TCP connection separately. */ if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) ret = tcp_write_packet(s, rtsp_st); return ret; }