Rawvideo в mp4 контейнер - PullRequest
       14

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

0 голосов
/ 14 февраля 2020

Как я могу транслировать код rawvideo c в контейнер 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, но если камера передает rawvideo, она не передается в файл и выдает ошибку.

РЕДАКТИРОВАТЬ Как и предполагалось, я пытаюсь закодировать его сейчас, но avcodec_send_frame() возвращает -22 и в файл ничего не сохраняется. Где я скучаю? Код отредактирован.

1 Ответ

1 голос
/ 14 февраля 2020

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

...