aboutsummaryrefslogtreecommitdiff
path: root/transmuxer.c
diff options
context:
space:
mode:
Diffstat (limited to 'transmuxer.c')
-rw-r--r--transmuxer.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/transmuxer.c b/transmuxer.c
index 4c0f993..e2f60fc 100644
--- a/transmuxer.c
+++ b/transmuxer.c
@@ -25,27 +25,30 @@ typedef struct {
AVStream *video_stream;
} StreamPair;
+#define OUT_VIDEO_STREAM_INDEX 0
+#define OUT_AUDIO_STREAM_INDEX 1
+
static StreamPair start_new_output_file(
AVFormatContext *in_fmt_ctx,
- AVFormatContext *out_fmt_ctx,
+ AVFormatContext **out_fmt_ctx,
const char *out_filename,
int aidx, int vidx) {
- avformat_alloc_output_context2(&out_fmt_ctx, NULL, "mpegts", out_filename);
+ avformat_alloc_output_context2(out_fmt_ctx, NULL, "mpegts", out_filename);
- AVStream *out_video_stream = avformat_new_stream(out_fmt_ctx, NULL);
- AVStream *out_audio_stream = avformat_new_stream(out_fmt_ctx, NULL);
+ AVStream *out_video_stream = avformat_new_stream(*out_fmt_ctx, NULL);
+ AVStream *out_audio_stream = avformat_new_stream(*out_fmt_ctx, NULL);
avcodec_parameters_copy(out_video_stream->codecpar, in_fmt_ctx->streams[vidx]->codecpar);
avcodec_parameters_copy(out_audio_stream->codecpar, in_fmt_ctx->streams[aidx]->codecpar);
- if (!(out_fmt_ctx->oformat->flags & AVFMT_NOFILE)) {
- if (avio_open(&out_fmt_ctx->pb, out_filename, AVIO_FLAG_WRITE) < 0) {
+ if (!((*out_fmt_ctx)->oformat->flags & AVFMT_NOFILE)) {
+ if (avio_open(&(*out_fmt_ctx)->pb, out_filename, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "Could not open output file '%s'\n", out_filename);
exit(-1);
}
}
- if (avformat_write_header(out_fmt_ctx, NULL) < 0) {
+ if (avformat_write_header(*out_fmt_ctx, NULL) < 0) {
fprintf(stderr, "avformat_write_header failed.\n");
abort();
}
@@ -57,8 +60,10 @@ static StreamPair start_new_output_file(
static int RingBuffer_avio_read(void *ctx, uint8_t *buf, int buf_size) {
RingBuffer *rb = ctx;
- if (rb->finished_flag) return AVERROR_EOF;
size_t n = RingBuffer_read(rb, buf, buf_size);
+ if (n == 0 && buf_size > 0) {
+ return AVERROR_EOF;
+ }
return (int)n;
}
@@ -66,12 +71,11 @@ AVIOContext* create_avio_from_ringbuffer(RingBuffer *rb, int buffer_size) {
uint8_t *avio_buf = av_malloc(buffer_size);
AVIOContext *avio = avio_alloc_context(
avio_buf, buffer_size,
- 0, // write_flag=0 => read only
+ 0,
rb,
- RingBuffer_avio_read, // read
- NULL, // write
- NULL // seek
- );
+ RingBuffer_avio_read,
+ NULL,
+ NULL);
return avio;
}
@@ -90,9 +94,10 @@ void* Transmuxer_main (void *vself) {
Transmuxer *self = vself;
pthread_mutex_lock(&self->lock);
while (wait_for_new_stream(self)) {
- AVFormatContext *in_fmt_ctx = NULL;
+ AVFormatContext *in_fmt_ctx = avformat_alloc_context();
in_fmt_ctx->pb = create_avio_from_ringbuffer(self->stream, 4096);
- if (avformat_open_input(&in_fmt_ctx, NULL, NULL, NULL) < 0) {
+ const AVInputFormat *flv_fmt = av_find_input_format("flv");
+ if (avformat_open_input(&in_fmt_ctx, NULL, flv_fmt, NULL) < 0) {
fprintf(stderr, "Could not open input file\n");
abort();
}
@@ -129,16 +134,15 @@ void* Transmuxer_main (void *vself) {
int64_t pts_time;
AVPacket pkt;
- StreamPair output_stream;
-
- output_stream = start_new_output_file(in_fmt_ctx, out_fmt_ctx, out_filename, audio_stream_index, video_stream_index);
+ StreamPair output_stream = start_new_output_file(
+ in_fmt_ctx, &out_fmt_ctx, out_filename, audio_stream_index, video_stream_index);
while (av_read_frame(in_fmt_ctx, &pkt) >= 0) {
AVStream *in_stream = in_fmt_ctx->streams[pkt.stream_index];
AVStream *out_stream = NULL;
if (pkt.stream_index == video_stream_index)
out_stream = output_stream.video_stream;
else if (pkt.stream_index == audio_stream_index)
- out_stream = output_stream.video_stream;
+ out_stream = output_stream.audio_stream;
else {
av_packet_unref(&pkt);
continue;
@@ -157,21 +161,21 @@ void* Transmuxer_main (void *vself) {
segment_index++;
segment_start_pts = pts_time;
snprintf(out_filename, sizeof(out_filename), "segment_%03d.ts", segment_index);
- start_new_output_file(in_fmt_ctx, out_fmt_ctx, out_filename, audio_stream_index, video_stream_index);
+ output_stream = start_new_output_file(in_fmt_ctx, &out_fmt_ctx, out_filename, audio_stream_index, video_stream_index);
}
}
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
- pkt.stream_index = (pkt.stream_index == video_stream_index) ? output_stream.video_stream->index : output_stream.audio_stream->index;
+ pkt.stream_index = (pkt.stream_index == audio_stream_index) ? OUT_AUDIO_STREAM_INDEX : OUT_VIDEO_STREAM_INDEX;
av_interleaved_write_frame(out_fmt_ctx, &pkt);
av_packet_unref(&pkt);
}
printf("new ts: %ld\n", pts_time - segment_start_pts);
finalize_output_file(out_fmt_ctx);
-
+
av_free(in_fmt_ctx->pb->buffer);
avio_context_free(&in_fmt_ctx->pb);
avformat_close_input(&in_fmt_ctx);