Skip to content
Snippets Groups Projects
Commit 03ba7991 authored by Julian Rother's avatar Julian Rother
Browse files

Added remux worker

parent 0d6772b9
No related branches found
No related tags found
No related merge requests found
remux.c 0 → 100644
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include "util.h"
#include "config.h"
static AVRational chapter_time_base = {1, 1};
void parse_dict(AVDictionary **d, char *s)
{
char key[JSTR_SIZE], value[JSTR_SIZE];
for (s = jenter(s); s; s = jnext(s))
av_dict_set(d, jstrb(s, 0, key), jstrb(jvalue(s), 0, value), 0);
}
void parse_chapters(AVFormatContext *ctx, char *s, int duration)
{
char *p;
int i;
for (p = jenter(s), i = 0; p; p = jnext(p), i ++);
ctx->chapters = malloc(sizeof(AVChapter *)*i);
ctx->nb_chapters = i;
for (p = jenter(s), i = 0; p; p = jnext(p), i ++)
{
ctx->chapters[i] = malloc(sizeof(AVChapter));
memset(ctx->chapters[i], 0, sizeof(AVChapter));
ctx->chapters[i]->id = i;
ctx->chapters[i]->time_base = chapter_time_base;
ctx->chapters[i]->start = jint(jlookup(p, "time"), 0);
av_dict_set(&ctx->chapters[i]->metadata, "title", jstr(jlookup(p, "text"), "EMPTY"), 0);
if (i)
ctx->chapters[i-1]->end = ctx->chapters[i]->start;
}
ctx->chapters[i-1]->end = duration;
}
int main(int argc, char *argv[])
{
int jobid, i;
int *idxmap;
char *p, path[100], tmp[100];
AVFormatContext *demux, *mux;
AVPacket pkt;
AVStream *stream;
if (argc != 5)
return 1;
av_register_all();
av_log_set_callback(avlogbuf_callback);
memset(&pkt, 0, sizeof(pkt));
av_init_packet(&pkt);
jobid = atoi(argv[1]);
xsnprintf(BL(path), "%s/%s", CONFIG_VIDEOS_RELEASED,
jstr(jlookup(argv[4], "path"), ""));
xsnprintf(BL(tmp), "%s/.tmp-%i", CONFIG_VIDEOS_TMP, jobid);
ping_job(jobid, "running", 0);
demux = 0;
if (avformat_open_input(&demux, path, 0, 0))
goto fail;
avformat_find_stream_info(demux, 0);
avformat_alloc_output_context2(&mux, 0, 0, path);
parse_dict(&mux->metadata, jlookup(argv[4], "metadata"));
parse_chapters(mux, jlookup(argv[4], "chapters"), av_rescale_q(demux->duration, AV_TIME_BASE_Q, chapter_time_base));
idxmap = malloc(sizeof(int)*demux->nb_streams);
for (i = 0; i < demux->nb_streams; i ++)
{
if (demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO
&& demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO
&& demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
{
idxmap[i] = -1;
continue;
}
stream = avformat_new_stream(mux, 0);
idxmap[i] = stream->index;
avcodec_parameters_copy(mux->streams[i]->codecpar,
demux->streams[i]->codecpar);
mux->streams[i]->codecpar->codec_tag = 0;
mux->streams[i]->time_base = demux->streams[i]->time_base;
}
avio_open(&mux->pb, tmp, AVIO_FLAG_WRITE);
if (avformat_write_header(mux, 0) < 0)
goto fail;
while (!av_read_frame(demux, &pkt))
{
if (pkt.stream_index >= demux->nb_streams
|| idxmap[pkt.stream_index] == -1)
continue;
pkt.stream_index = idxmap[pkt.stream_index];
pkt.pts = av_rescale_q_rnd(pkt.pts, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base);
pkt.pos = -1;
if (av_interleaved_write_frame(mux, &pkt))
goto fail;
}
av_interleaved_write_frame(mux, 0);
if (av_write_trailer(mux))
goto fail;
avio_closep(&mux->pb);
if (rename(tmp, path))
goto fail;
unlink(tmp);
ping_job(jobid, "finished", "{\"log\": \"%s\"}", get_avlogbuf());
return 0;
fail:
unlink(tmp);
ping_job(jobid, "failed", "{\"log\": \"%s\"}", get_avlogbuf());
return 1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment