Rawvideo в контейнер mp4

Как я могу транслировать кодек rawvideo в контейнер mp4? Ошибка Could not find tag for codec rawvideo in stream #0, codec not currently supported in container. URL-адрес, например, video=Logitech HD Webcam C270, а формат - dshow. Имя файла скажем out.mp4

AVFormatContext* pInputFmtCtx = avformat_alloc_context();
AVInputFormat* inputFormat = av_find_input_format(Format);

avformat_open_input(&pInputFmtCtx, url, inputFormat, null);
if (avformat_find_stream_info(pInputFmtCtx, null) != -1)
   ... find stream index

AVCodec* videoDecoder = avcodec_find_decoder(pInputFmtCtx->streams[_vidStreamIndex]->codecpar->codec_id);

AVCodecContext* videcCodecCtx = avcodec_alloc_context3(videoDecoder);
avcodec_parameters_to_context(videcCodecCtx, videoCodecParams);

avcodec_open2(videcCodecCtx, videoDecoder, null);

// and the output context
AVFormatContext* pOutputFmtCtx = null;
avformat_alloc_output_context2(&pOutputFmtCtx, null, null, fileName);

// iterate over streams of input context and when we find it
AVStream* in_stream = pInputFmtCtx->streams[i];
AVCodecParameters* in_codecpar = in_stream->codecpar;

AVStream* out_stream = avformat_new_stream(pOutputFmtCtx, null);

// init h264 encoder
AVCodec* videoEncoder = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_H264);
pVideoEncoderCodecContext = ffmpeg.avcodec_alloc_context3(videoEncoder);

pVideoEncoderCodecContext->time_base = videcCodecCtx->time_base;
pVideoEncoderCodecContext->framerate = videcCodecCtx->framerate;
pVideoEncoderCodecContext->width = videcCodecCtx->width;
pVideoEncoderCodecContext->height = videcCodecCtx->height;
pVideoEncoderCodecContext->bit_rate = videcCodecCtx->bit_rate;
pVideoEncoderCodecContext->gop_size = videcCodecCtx->gop_size;
pVideoEncoderCodecContext->pix_fmt = AVPixelFormat.AV_PIX_FMT_YUV420P;
pVideoEncoderCodecContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;

// copy parameters to outstream codec
avcodec_parameters_copy(out_stream->codecpar, in_codecpar);

....

// after that
avio_open(&pOutputFmtCtx->pb, fileName, AVIO_FLAG_WRITE);
avformat_write_header(pOutputFmtCtx, &opts);

// and reading
while (av_read_frame(pInputFormatContext, pkt) >= 0)

// decode 
avcodec_send_packet(videcCodecCtx, pkt);
//receive the raw frame from the decoder
avcodec_receive_frame(videcCodecCtx, frame);

// now encode if its video packet
int ret = avcodec_send_frame(pVideoEncoderCodecContext, frame);
if (ret < 0)
{
    continue;
}

while (ret >= 0)
{
    ret = avcodec_receive_packet(pVideoEncoderCodecContext, packet);

    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
    {
           return;
    }

    av_packet_rescale_ts(packet, pVideoEncoderCodecContext->time_base, pOutputFmtCtx->streams[packet->stream_index]->time_base);
    av_interleaved_write_frame(pOutputFmtCtx, pkt);

    av_packet_unref(packet);
}

Это прекрасно работает, если камера передает H264, но если камера передает необработанное видео, оно не передает поток в файл и выдает ошибку.

EDIT Как и было предложено, я пытаюсь закодировать его сейчас, но avcodec_send_frame() возвращает -22, и в файл ничего не сохраняется. Где я скучаю? Код отредактирован.


person Expressingx    schedule 14.02.2020    source источник
comment
Сохранить как .mov или .mkv   -  person Gyan    schedule 14.02.2020


Ответы (1)


MP4 не поддерживает rawvideo. Вы должны либо закодировать его в другой формат, либо использовать контейнер, который его поддерживает.

person szatmary    schedule 14.02.2020
comment
Ага, как? Мне нужен не полный код, а направление - person Expressingx; 14.02.2020
comment
Код редактировал кодировщиком, ошибок нет, в файле тоже ничего. avcodec_send_frame() возвращает -22, и я не знаю, почему. - person Expressingx; 21.02.2020