Commit 03ba7991 authored by Julian Rother's avatar Julian Rother

Added remux worker

parent 0d6772b9
#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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment