Hi all,

I have the following issue: I'm working on a file (has 1 audio and 1 video streams) modify (decode, modify the pixel data and encode) the frames in them and write the modified frames to a new file. The video stream is h264. The problem is that highly possible I'm not setting up something correctly, since although that the result file has both the video and audio streams, when I try to play it it gives me errors like:

[h264 @ 0x25ff8e0]AVC: nal size 559836223
[h264 @ 0x25ff8e0]no frame!

and I hear no audio. Now, on the other end if I do the same thing with a file which has mpeg4 video, everything works nicely, there is video and audio too in the overlayed file

I share with you the interesting parts from the source, maybe someone has some experience in this and will pick the missing bits... it's something to do with the way H264 is set up and works...

Thanks
frc

CODE SNIPPETS BELOW

// <-- load of the streams, is done before I reach this point ... -->

// codecForOverlayedMovie is the codec which is used to encode a frame which was modified (overlayed :) ). if I set it up for CODEC_ID_MPEG4 it works nicely

    codecForOvlerlayedMovie = avcodec_find_encoder(CODEC_ID_H264);
    if (!codecForOvlerlayedMovie)
    {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    contextForOverlayedMovie = avcodec_alloc_context();
    contextForOverlayedMovie->codec_id = CODEC_ID_H264,
    contextForOverlayedMovie->codec_type = CODEC_TYPE_VIDEO;

    contextForOverlayedMovie->bit_rate = 400000;
contextForOverlayedMovie->time_base.den = 25; contextForOverlayedMovie->time_base.num = 1;
    contextForOverlayedMovie->width = w;
    contextForOverlayedMovie->height =h;
    contextForOverlayedMovie->dct_algo = 0;
    contextForOverlayedMovie->gop_size = 10;
    contextForOverlayedMovie->me_pre_cmp=2;
    contextForOverlayedMovie->cqp = 26;
    contextForOverlayedMovie->max_qdiff = 5;
    contextForOverlayedMovie->max_b_frames=1;
    contextForOverlayedMovie->qblur = 0.5;
    contextForOverlayedMovie->i_quant_factor = (float)0.8;
    contextForOverlayedMovie->pix_fmt = PIX_FMT_YUV420P;

    contextForOverlayedMovie->me_range = 4;
    contextForOverlayedMovie->qmin = 4;
    contextForOverlayedMovie->qmin = 30;
    contextForOverlayedMovie->qcompress = 1.0;

    /* open it */
if (avcodec_open(contextForOverlayedMovie, codecForOvlerlayedMovie) < 0)
    {
        fprintf(stderr, "could not open codec 1\n");
        exit(1);
    }

 main loop below

    while (av_read_frame(ic, &packet) >= 0)
    {
        if (packet.stream_index == in_video_stream_index)
        {
            vpcnt++; //video packet counter
            // the pFrame variable holds the decoded video
avcodec_decode_video2(pVCodecCtx, pFrame, &frameFinished, &packet);

            if (frameFinished)
            {
// the picture variable is the one that gets modified and then re-encoded in the output stream sws_scale(img_work_ctx, pFrame->data, pFrame->linesize, 0, pVCodecCtx->height, picture->data, picture->linesize);

                /* apply some "overlay" on the picture */
                for (y = 0; y < contextForOverlayedMovie->height; y++)
                {
                    for (x = y; x < contextForOverlayedMovie->width; x++)
                    {
picture->data[0][y * picture->linesize[0] + x] = vpcnt;
                    }
                }

                /* Cb and Cr */
                for (y = 0; y < contextForOverlayedMovie->height / 2; y++)
                {
for (x = y; x < contextForOverlayedMovie->width / 2; x++)
                    {
picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
                    }
                }

                /* encode the video with the overlay applied */
out_size = avcodec_encode_video(contextForOverlayedMovie, outbuf, outbuf_size, picture);

/* duplicate, so that we don't free multiple times with av_free_packet. outbuf is allocated only once earlier in the app */ uint8_t* dup_outbuf = (uint8_t*)malloc(sizeof(uint8_t) * out_size + 1);
                memcpy(dup_outbuf, outbuf, out_size);

                // this is a little bit ugly ... but seems to work
                free(packet.data);
                packet.data = dup_outbuf;
                packet.size = out_size;

// TEST: this writes the frames to a temporary file. the frames are correctly encoded and put in the file!!!
                fwrite(outbuf, 1, out_size, f);

                oc->oformat->write_packet(oc, &packet);
            }
            else
            {
                oc->oformat->write_packet(oc, &packet);
            }

        }
        else
        if (packet.stream_index == in_audio_stream_index)
        { //audio packet
            oc->oformat->write_packet(oc, &packet);
        }
        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
    }

_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to