I forgot to paste my code
-(void) writeVideoFrame:(AVStream*)st
{
int out_size, ret;
AVCodecContext *c;
static struct SwsContext *img_convert_ctx;
c = st->codec;
//if (frame_count >= STREAM_NB_FRAMES)
//{
/* no more frame to compress. The codec has a latency of a few
frames if using B frames, so we get the last frames by
passing the same picture again */
//}
//else
//{
if (c->pix_fmt != PIX_FMT_YUV420P)
{
/* as we only generate a YUV420P picture, we must convert it
to the codec pixel format if needed */
if (img_convert_ctx == NULL)
{
img_convert_ctx = sws_getContext(c->width, c->height,
PIX_FMT_YUV420P,
c->width, c->height,
c->pix_fmt,
SWS_BICUBIC, NULL, NULL, NULL);
if (img_convert_ctx == NULL)
{
NSLog(@"Cannot initialize the conversion context\n");
return;
}
}
[self fillYUVImage:tmp_picture frame_index:frame_count];
sws_scale(img_convert_ctx, tmp_picture->data,
tmp_picture->linesize,0, c->height, picture->data, picture->linesize);
}
else
{
[self fillYUVImage:picture frame_index:frame_count];
}
//}
if (pFmtCtx->oformat->flags & AVFMT_RAWPICTURE)
{
/* raw video case. The API will change slightly in the near
futur for that */
AVPacket pkt;
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index= st->index;
pkt.data= (uint8_t *)picture;
pkt.size= sizeof(AVPicture);
ret = av_interleaved_write_frame(pFmtCtx, &pkt);
}
else
{
/* encode the image */
picture->pts = frame_count * 40 * 90;
out_size = avcodec_encode_video(c, video_outbuf,
video_outbuf_size, picture);
/* if zero size, it means the image was buffered */
if (out_size > 0) {
AVPacket pkt;
av_init_packet(&pkt);
if (c->coded_frame->pts != AV_NOPTS_VALUE)
{
pkt.pts= av_rescale_q(c->coded_frame->pts,
c->time_base, st->time_base);
pkt.dts = encodedFrames * 40 * 90;
}
if(c->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index= st->index;
pkt.data= video_outbuf;
pkt.size= out_size;
/* write the compressed frame in the media file */
ret = av_interleaved_write_frame(pFmtCtx, &pkt);
encodedFrames++;
}
else
{
ret = 0;
}
}
if (ret != 0)
{
NSLog(@"Error while writing video frame");
return;
}
frame_count++;
}
On Wed, Feb 2, 2011 at 4:36 PM, Gautam Muralidhar
<[email protected]> wrote:
> Sven,
> This is how I am writing my frame.
> Do you see anything wrong with this method?
> It works fine for non-h264 videos but for h264 videos something
> doesn't seem to add up.
> Thanks
> Gautam
>
> On Tue, Feb 1, 2011 at 12:11 PM, Sven Alisch <[email protected]> wrote:
>> Dear Gautam,
>>
>> This really no problem, because I was a bloody beginner and the people here
>> helped me very much. If you need code, don't hestitate to post it and ask.
>>
>> regards,
>> Sven
>>
>> Am 01.02.2011 um 21:04 schrieb Gautam Muralidhar:
>>
>>> Sven,
>>> This is great, thanks again. Please excuse me for beginner questions.
>>> I may have to bother you in the near future with more info :)
>>> Thanks in advance
>>> Gautam
>>>
>>> On Tue, Feb 1, 2011 at 12:03 PM, Sven Alisch <[email protected]> wrote:
>>>> Gautam,
>>>>
>>>>> my case I dont cut frames at all. So I assume that the calculation of
>>>>> my pts and dts would be something like frameNR*40*90 like in your
>>>>> case?
>>>>
>>>> For the dts you have got right. The pts you don't need to calculate
>>>> because you get the pts as a present by avcodec_encode_video-function.
>>>>
>>>> regards,
>>>> Sven
>>>>
>>>>> Thanks
>>>>> Gautam
>>>>>
>>>>> On Tue, Feb 1, 2011 at 11:53 AM, Sven Alisch <[email protected]> wrote:
>>>>>> Gautam,
>>>>>>
>>>>>>> What are your magic numbers in your math? 40*90 and 120*90?
>>>>>>
>>>>>> Sorry for the hard coded magic numbers. My code is quick and dirty. I
>>>>>> have to do a finetuning now.
>>>>>>
>>>>>> 40*90 means 40 ms (because in germany the duration of a frame is 40 ms)
>>>>>> and 90 because of the 90kHz by the standard for PTS-values.
>>>>>>
>>>>>>> Also where do you get decodeToFrame value?
>>>>>>
>>>>>> Oh this is my own variable. The background is following. My program
>>>>>> should cut not only at keyframes. If I cut not at a keyframe, then I
>>>>>> reencode my "open" GOP. So decodeToFrame tells me, how many frames to
>>>>>> decode till the position where I have to reencode my stream.
>>>>>>
>>>>>> Example:
>>>>>>
>>>>>> My GOP structure
>>>>>>
>>>>>> IBPBPBPPP...
>>>>>>
>>>>>> Lets assume I want to cut my videofile at the 3'rd position. Now
>>>>>> decodeToFrame is 3. But I have to decode the whole GOP including the
>>>>>> first key frame. At the 3'rd frame I reencode and create a new coded
>>>>>> shorter sequence. My english is bad, but did you understand?
>>>>>>
>>>>>> regards,
>>>>>> Sven
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Feb 1, 2011 at 11:34 AM, Sven Alisch <[email protected]> wrote:
>>>>>>>> Dear Gautam, dear Max,
>>>>>>>>
>>>>>>>> Thank you for your proposals. Now it works. The main problem (I think)
>>>>>>>> depends on the avframe. This avframe was the direct output from the
>>>>>>>> decoder. So this avframe contains many informations that disturbs the
>>>>>>>> encoder. I show the solution (quick and dirty code! No memory cleanup
>>>>>>>> and so on... ) at the end of my mail.
>>>>>>>>
>>>>>>>> @Max
>>>>>>>>
>>>>>>>> You've got right. It is better to comment the last one out.
>>>>>>>>
>>>>>>>> @Gautam
>>>>>>>>
>>>>>>>> Yes of course. No problem. Here is my code.
>>>>>>>>
>>>>>>>> if (frameFinished)
>>>>>>>>
>>>>>>>> // Here the decoder is finished and decode a
>>>>>>>> frame from an existent h.264 stream
>>>>>>>> {
>>>>>>>> frameNr++;
>>>>>>>>
>>>>>>>> if (frameNr >= decodeToFrame)
>>>>>>>> {
>>>>>>>> AVCodecContext* c = t->streamContext->codec;
>>>>>>>>
>>>>>>>> AVFrame* newFrame = avcodec_alloc_frame();
>>>>>>>>
>>>>>>>> // Initialize a new frame
>>>>>>>> int size = avpicture_get_size(c->pix_fmt, c->width,
>>>>>>>> c->height);
>>>>>>>> uint8_t* picture_buf = av_malloc(size);
>>>>>>>> avpicture_fill((AVPicture *)newFrame, picture_buf,
>>>>>>>> c->pix_fmt, c->width, c->height);
>>>>>>>> av_picture_copy((AVPicture*)newFrame,
>>>>>>>> (AVPicture*)avframe, c->pix_fmt, c->width, c->height); // Copy only
>>>>>>>> the frame content without any other disturbing stuff
>>>>>>>>
>>>>>>>> newFrame->pts = (frameNr - decodeToFrame)*40*90;
>>>>>>>>
>>>>>>>> // Setting correct pts
>>>>>>>>
>>>>>>>> int out_size = avcodec_encode_video(c, video_outbuf,
>>>>>>>> video_outbuf_size, newFrame);
>>>>>>>> if (out_size > 0)
>>>>>>>> {
>>>>>>>> av_init_packet(&tmp_packet);
>>>>>>>>
>>>>>>>> if (c->coded_frame->pts != AV_NOPTS_VALUE)
>>>>>>>> {
>>>>>>>> tmp_packet.pts =
>>>>>>>> av_rescale_q(c->coded_frame->pts,
>>>>>>>>
>>>>>>>> c->time_base,
>>>>>>>>
>>>>>>>> c->time_base) + 120*90;
>>>>>>>> tmp_packet.dts = encodedFrames*40*90;
>>>>>>>> }
>>>>>>>> if(c->coded_frame->key_frame)
>>>>>>>> tmp_packet.flags |= AV_PKT_FLAG_KEY;
>>>>>>>> tmp_packet.stream_index=
>>>>>>>> t->streamContext->index;
>>>>>>>> tmp_packet.data= video_outbuf;
>>>>>>>> tmp_packet.size= out_size;
>>>>>>>> av_interleaved_write_frame(formatContext,
>>>>>>>> &tmp_packet);
>>>>>>>> encodedFrames++;
>>>>>>>> }
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> regards,
>>>>>>>> Sven
>>>>>>>>
>>>>>>>> Am 01.02.2011 um 18:36 schrieb Gautam Muralidhar:
>>>>>>>>
>>>>>>>>> Sven,
>>>>>>>>> I am seeing similar issues. How exactly are you writing your frames?
>>>>>>>>> Do you think you can share your code inside the
>>>>>>>>> if(outsize >0)
>>>>>>>>> {
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>> Gautam
>>>>>>>>> On Tue, Feb 1, 2011 at 6:15 AM, Max The Quantum <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>> I've tried your config, but uncommented all lines except
>>>>>>>>>> //c->flags2|=CODEC_FLAG2_8X8DCT;
>>>>>>>>>> //c->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8
>>>>>>>>>> and commented out
>>>>>>>>>> c->crf = 22;
>>>>>>>>>>
>>>>>>>>>> It seems that problem is caused by wrong value of c->keyint_min.
>>>>>>>>>> What is
>>>>>>>>>> default value for it?
>>>>>>>>>> Try to set it manually to, say, 25 :)
>>>>>>>>>>
>>>>>>>>>> 2011/2/1 Sven Alisch <[email protected]>
>>>>>>>>>>
>>>>>>>>>>> Hello list,
>>>>>>>>>>>
>>>>>>>>>>> I want to (re-) encode some pictures I decoded with libav. The
>>>>>>>>>>> following
>>>>>>>>>>> code shows how I do that:
>>>>>>>>>>>
>>>>>>>>>>> First I decode an h.264 Stream and get pictures in an AVFrame
>>>>>>>>>>> structure.
>>>>>>>>>>> After doing this I want to encode them into an h.264 stream.
>>>>>>>>>>> <snip>
>>>>>>>>>>> bytesDecoded =
>>>>>>>>>>> avcodec_decode_video2(m->videofile->VideoTrack->codec_context,
>>>>>>>>>>> avframe,
>>>>>>>>>>> &frameFinished, &packet);
>>>>>>>>>>>
>>>>>>>>>>> if (frameFinished)
>>>>>>>>>>> {
>>>>>>>>>>> frameNr++;
>>>>>>>>>>>
>>>>>>>>>>> if (frameNr >= decodeToFrame)
>>>>>>>>>>> {
>>>>>>>>>>> AVCodecContext* c = t->streamContext->codec;
>>>>>>>>>>> avframe->pts = (frameNr - decodeToFrame)*40*90;
>>>>>>>>>>> int out_size = avcodec_encode_video(c, video_outbuf,
>>>>>>>>>>> video_outbuf_size, avframe);
>>>>>>>>>>> if (out_size > 0)
>>>>>>>>>>> {
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>> <snap>
>>>>>>>>>>>
>>>>>>>>>>> My Encoding parameters for x264 are set in a function like this:
>>>>>>>>>>>
>>>>>>>>>>> bool h264_initEncoder(AVFormatContext* fc, tavtrack_t* track)
>>>>>>>>>>> {
>>>>>>>>>>> AVCodec* codec = NULL;
>>>>>>>>>>> AVCodecContext* c = NULL;
>>>>>>>>>>>
>>>>>>>>>>> c = track->streamContext->codec;
>>>>>>>>>>> c->profile = track->codec_context->profile; // original
>>>>>>>>>>> set by
>>>>>>>>>>> libavformat/libavcodec
>>>>>>>>>>> c->level = track->codec_context->level; // original
>>>>>>>>>>> set by
>>>>>>>>>>> libavformat/libavcodec
>>>>>>>>>>>
>>>>>>>>>>> // Medium Profile
>>>>>>>>>>> // libx264-medium.ffpreset preset
>>>>>>>>>>> c->coder_type = FF_CODER_TYPE_AC; // coder = 1
>>>>>>>>>>> c->flags |= CODEC_FLAG_LOOP_FILTER; // flags=+loop
>>>>>>>>>>> c->me_cmp|= 1; //
>>>>>>>>>>> cmp=+chroma, where CHROMA = 1
>>>>>>>>>>> c->partitions |=
>>>>>>>>>>> X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8;
>>>>>>>>>>>
>>>>>>>>>>> // partitions=+parti8x8+parti4x4+partp8x8+partb8x8
>>>>>>>>>>> c->me_method=ME_HEX; //
>>>>>>>>>>> me_method=hex
>>>>>>>>>>> c->me_subpel_quality = 7; // subq=7
>>>>>>>>>>> c->me_range = 16; //
>>>>>>>>>>> me_range=16
>>>>>>>>>>> //c->gop_size = 250; //
>>>>>>>>>>> g=250
>>>>>>>>>>> //c->keyint_min = 25; //
>>>>>>>>>>> keyint_min=25
>>>>>>>>>>> c->scenechange_threshold = 40; // sc_threshold=40
>>>>>>>>>>> //c->i_quant_factor = 0.71; //
>>>>>>>>>>> i_qfactor=0.71
>>>>>>>>>>> //c->b_frame_strategy = 1; //
>>>>>>>>>>> b_strategy=1
>>>>>>>>>>> c->qcompress = 0.6; //
>>>>>>>>>>> qcomp=0.6
>>>>>>>>>>> c->qmin = 10; //
>>>>>>>>>>> qmin=10
>>>>>>>>>>> c->qmax = 51; //
>>>>>>>>>>> qmax=51
>>>>>>>>>>> c->max_qdiff = 4; //
>>>>>>>>>>> qdiff=4
>>>>>>>>>>> c->max_b_frames = 3; // bf=3
>>>>>>>>>>> c->refs = 3; //
>>>>>>>>>>> refs=3
>>>>>>>>>>> //c->directpred = 1; //
>>>>>>>>>>> directpred=1
>>>>>>>>>>> //c->trellis = 1;
>>>>>>>>>>> //
>>>>>>>>>>> trellis=1
>>>>>>>>>>> c->flags2 |=
>>>>>>>>>>> CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP;
>>>>>>>>>>>
>>>>>>>>>>> // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
>>>>>>>>>>> c->weighted_p_pred = 2; // wpredp=2
>>>>>>>>>>>
>>>>>>>>>>> // libx264-main.ffpreset preset
>>>>>>>>>>> //c->flags2|=CODEC_FLAG2_8X8DCT;
>>>>>>>>>>> //c->flags2^=CODEC_FLAG2_8X8DCT; //
>>>>>>>>>>> flags2=-dct8x8
>>>>>>>>>>> c->crf = 22;
>>>>>>>>>>> codec = avcodec_find_encoder(c->codec_id);
>>>>>>>>>>> if (!codec)
>>>>>>>>>>> return false;
>>>>>>>>>>>
>>>>>>>>>>> if (avcodec_open(c, codec) < 0)
>>>>>>>>>>> return false;
>>>>>>>>>>>
>>>>>>>>>>> return true;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> The Problem is, that the avcode_encode_video( ... ) works but no
>>>>>>>>>>> frame will
>>>>>>>>>>> be compressed. I get strange errors like this:
>>>>>>>>>>>
>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (5) at 0 is not
>>>>>>>>>>> compatible
>>>>>>>>>>> with keyframe interval
>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (5) at 1 is not
>>>>>>>>>>> compatible
>>>>>>>>>>> with keyframe interval
>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (3) at 2 is not
>>>>>>>>>>> compatible
>>>>>>>>>>> with keyframe interval
>>>>>>>>>>>
>>>>>>>>>>> I get no frame. But why? Does anybody has an hint for me? Are my
>>>>>>>>>>> parameters
>>>>>>>>>>> wrong?
>>>>>>>>>>>
>>>>>>>>>>> regards,
>>>>>>>>>>> Sven
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> libav-user mailing list
>>>>>>>>>>> [email protected]
>>>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> libav-user mailing list
>>>>>>>>>> [email protected]
>>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Gautam Muralidhar
>>>>>>>>> Code Particle Inc.
>>>>>>>>> (805)-501-0700
>>>>>>>>> _______________________________________________
>>>>>>>>> libav-user mailing list
>>>>>>>>> [email protected]
>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> libav-user mailing list
>>>>>>>> [email protected]
>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Gautam Muralidhar
>>>>>>> Code Particle Inc.
>>>>>>> (805)-501-0700
>>>>>>> _______________________________________________
>>>>>>> libav-user mailing list
>>>>>>> [email protected]
>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>
>>>>>> _______________________________________________
>>>>>> libav-user mailing list
>>>>>> [email protected]
>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Gautam Muralidhar
>>>>> Code Particle Inc.
>>>>> (805)-501-0700
>>>>> _______________________________________________
>>>>> libav-user mailing list
>>>>> [email protected]
>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>
>>>> _______________________________________________
>>>> libav-user mailing list
>>>> [email protected]
>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>
>>>
>>>
>>>
>>> --
>>> Gautam Muralidhar
>>> Code Particle Inc.
>>> (805)-501-0700
>>> _______________________________________________
>>> libav-user mailing list
>>> [email protected]
>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>
>> _______________________________________________
>> libav-user mailing list
>> [email protected]
>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>
>
>
>
> --
> Gautam Muralidhar
> Code Particle Inc.
> (805)-501-0700
>
--
Gautam Muralidhar
Code Particle Inc.
(805)-501-0700
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user