ireader / media-server

RTSP/RTP/RTMP/FLV/HLS/MPEG-TS/MPEG-PS/MPEG-DASH/MP4/fMP4/MKV/WebM
MIT License
3.06k stars 1.07k forks source link

264转mp4 ,使用mov_writer-h264.cpp中的代码,mp4文件vlc不能播放,能帮忙看下吗?附件有生成的mp4文件,这种现象有的可以,有的不行。 #323

Closed menglingbo closed 8 months ago

menglingbo commented 8 months ago

void h264_handler(void param, const uint8_t nalu, size_t bytes,long long llTs) { static uint8_t startcode[] = {0x00, 0x00, 0x00, 0x01}; va_mov ctx = (va_mov)param;

uint8_t nalutype = nalu[0] & 0x1f;

if (ctx->vcl > 0 && h264_is_new_access_unit((const uint8_t*)nalu, bytes))
{
    int r = h264_write(ctx, ctx->buf, ctx->bytes,llTs);
    if (-1 == r)
        return; // wait for more data
    ctx->bytes = 0;
    ctx->vcl = 0;
}

if (nalu_type_slice <= nalutype && nalutype <= nalu_type_idr)
{
    ++ctx->vcl;
    if (1 == ctx->vcl)
    {
        memcpy(ctx->buf + ctx->bytes, startcode, sizeof(startcode));
        ctx->bytes += sizeof(startcode);
        memcpy(ctx->buf + ctx->bytes, nalu, bytes);
        ctx->bytes += bytes;
    }
}
else
{
    memcpy(ctx->buf + ctx->bytes, startcode, sizeof(startcode));

    ctx->bytes += sizeof(startcode);
    memcpy(ctx->buf + ctx->bytes, nalu, bytes);
    ctx->bytes += bytes;
}

}

int h264_write(va_mov ctx, const void data, int bytes,long long llTs) { int vcl = 0; int update = 0; uint8_t ptr=( uint8_t )data;

int n = h264_annexbtomp4(&ctx->avc, data, bytes, s_buffer, sizeof(s_buffer), &vcl, &update);

if (ctx->track < 0)
{
    if (ctx->avc.nb_sps < 1 || ctx->avc.nb_pps < 1)
    {
        //ctx->ptr = end;
        return -2; // waiting for sps/pps
    }

    int extra_data_size = mpeg4_avc_decoder_configuration_record_save(&ctx->avc, s_extra_data, sizeof(s_extra_data));
    if (extra_data_size <= 0)
    {
        // invalid AVCC
        assert(0);
        return -1;
    }

    // TODO: waiting for key frame ???
    ctx->track = mp4_writer_add_video(ctx->mov, MOV_OBJECT_H264, ctx->width, ctx->height, s_extra_data, extra_data_size);
    if (ctx->track < 0)
        return -1;
    mp4_writer_init_segment(ctx->mov);
}
// mp4_writer_write(ctx->mov, ctx->track, s_buffer, n, llTs, llTs, 1 == vcl ? MOV_AV_FLAG_KEYFREAME : 0);
mp4_writer_write(ctx->mov, ctx->track, s_buffer, n, ctx->pts, ctx->pts, 1 == vcl ? MOV_AV_FLAG_KEYFREAME : 0);
ctx->pts += 1000/ctx->fps;
ctx->dts += 1000/ctx->fps;
return 0;

}

https://github.com/ireader/media-server/assets/5715627/e68ad5dc-f0a1-48e2-8fd1-2214d21c7220

https://github.com/ireader/media-server/assets/5715627/8d048e0e-0d5e-431b-8697-01738c3566f8

menglingbo commented 8 months ago

经常dump在 libflv/source/mpeg4_h264_read_ue函数的assert(leadingZeroBits < 32);这个地方

ireader commented 8 months ago

把原始H264文件也上传下?

menglingbo commented 8 months ago

nalutype序列 如果是这个样子的,7 8 5 1 1 21 1 1 1 1 1 21 1 1 1 1 1会有这个问题,我把21 扔掉就可以了

ireader commented 8 months ago

21 Coded slice extension for a depth view component or a 3D-AVC texture view component slice_layer_extension_rbsp( )

源文件是3D流吗?

menglingbo commented 8 months ago

不确定是不是3D流,通过ffprobe看到这些信息 Metadata: title : VCP IPC Realtime stream Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720, 25 fps, 25 tbr, 90k tbn, 50 tbc Stream #0:1: Audio: pcm_mulaw, 8000 Hz, 1 channels, s16, 64 kb/s Stream #0:2: Data: none

ireader commented 8 months ago

mov_writer-h264.cpp只支持264裸流文件, 如果是带音频的文件, 需要单独处理.