How does FFMPEG copy work?

Tyler Brooks picture Tyler Brooks · Nov 20, 2017 · Viewed 7.5k times · Source

How can I implement the equivalent of this command:

ffmpeg -i test.h264 -vcodec copy -hls_time 5 -hls_list_size 0 foo.m3u8

My understanding is that you do something like this (pseudo code for clarity):

avformat_open_input(&ctx_in, "test.h264", NULL, NULL);
avformat_find_stream_info(ctx_in, NULL);

avformat_alloc_output_context2(&ctx_out, NULL, "hls", "foo.m3u8");
strm_out = avformat_new_stream(ctx_out, NULL);
strm_out->time_base = (AVRational){1000000, FRAMERATE};

strm_out->codecpar->codec_id = AV_CODEC_ID_H264;
strm_out->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
strm_out->codecpar->width = width;
strm_out->codecpar->height = height;
strm_out->codecpar->bit_rate = bitrate;
strm_out->codecpar->codec_tag = 0;

avcodec_parameters_copy(ctx_out->streams[0]->codecpar,
  ctx_in->streams[0]->codecpar);

avformat_write_header(ctx_out, NULL);

while(1) {
  AVPacket pkt;

  ret = av_read_frame(ctx_in, &pkt);
  if (ret < 0)
    break;

  pkt.pos = -1;
  pkt.stream_index = 0;
  pkt.dts = AV_NOPTS_VALUE;
  pkt.pts = AV_NOPTS_VALUE;
  pkt.pts = SOME_DURATION;

  av_write_frame(ctx_out, &pkt);
  av_packet_unref(&pkt);
}
avformat_close_input(&ctx_in);
av_write_trailer(ctx_out);
avformat_free_context(ctx_out);

I crash on the avformat_find_stream_info() call. I think this is the case because an H264 elemental stream is not really a container (which avformat wants).

What is the proper way to implement the FFMPEG 'copy' command of an elemental stream?

Answer