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