Decoding raw H.264 annex B stream
4ernov
4ernov at gmail.com
Fri Nov 9 14:45:12 PST 2012
Hello,
I saw this case already discussed several times before but still quite
unobvious one, so I decided to raise it once more.
I've got a network client application which receives a stream of raw H.264
video data encoded as annex b. The stream is depayed properly and video
data packets go to avcodec_decode_video2() ffmpeg/libav function to be
decoded like this:
AVPacket pkt;
pkt.dts = unit->pts();
pkt.pts = unit->dts();
pkt.data = unit->data();
pkt.size = unit->size();
if (unit->isRap()) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
int isFrameFinished(0);
if (0 >= avcodec_decode_video2(codecCtx_, frame_, &isFrameFinished, &pkt)) {
printf("oops\n");
return;
}
if (isFrameFinished) {
*_frame = frame_;
*width = codecCtx_->width;
*height = codecCtx_->height;
*pixFmt = codecCtx_->pix_fmt;
}
The code above decodes the stream successfully. Now I need to switch the
processing to GStreamer but got stuck with a problem. I use appsrc to
inject data to the pipeline, the pipeline is like this:
appsrc -> h264parse -> ffdec_h264 -> ffmpegcolorspace -> ximagesink
I've set appsrc the following caps:
video/x-h264,width=960,height=580,framerate=25/1 and push buffers with the
same caps:
GstBuffer* buffer = gst_buffer_new();
gst_buffer_set_data(buffer, const_cast<unsigned char*>(unit->data()),
unit->size());
if (unit->isRap())
GST_BUFFER_FLAGS(buffer) |= GST_BUFFER_FLAG_DELTA_UNIT;
GstCaps* video_caps = gst_caps_new_simple ("video/x-h264",
"width", G_TYPE_INT, 960,
"height", G_TYPE_INT, 540,
"framerate", GST_TYPE_FRACTION, 25, 1,
NULL);
gst_buffer_set_caps(buffer, video_caps);
GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(videosource),
buffer);
The problem is that ffdec_h264 element throws some error messages and
provides no output, the pipeline is dry. Here's some messages of interest
from the LOG level output. ERROR level:
0:00:17.436071901 15944 0xfd8630 ERROR ffmpeg :0::
non-existing PPS referenced
0:00:17.436199850 15944 0xfd8630 ERROR ffmpeg :0::
slice type too large (0) at 0 0
0:00:17.436217450 15944 0xfd8630 ERROR ffmpeg :0::
decode_slice_header error
0:00:17.436239240 15944 0xfd8630 ERROR ffmpeg :0::
slice type too large (0) at 0 0
0:00:17.436255444 15944 0xfd8630 ERROR ffmpeg :0::
decode_slice_header error
0:00:17.436335063 15944 0xfd8630 ERROR ffmpeg :0:: no
frame!
and LOG-level (these messages seem to repeat for each buffer):
99:99:99.999999999, dur 99:99:99.999999999, size 109, offset
18446744073709551615, offset_end 18446744073709551615, caps: video/x-h264,
width=(int)960, height=(int)540, framerate=(fraction)25/1,
parsed=(boolean)true, stream-format=(string)byte-stream,
alignment=(string)au
0:00:42.490123738 15944 0xfd8630 LOG ffmpeg
gstffmpegdec.c:2622:gst_ffmpegdec_chain:<decoder> Received new data of size
109, offset:18446744073709551615, ts:99:99:99.999999999,
dur:99:99:99.999999999, info 98
0:00:42.490146087 15944 0xfd8630 LOG ffmpeg
gstffmpegdec.c:2660:gst_ffmpegdec_chain:<decoder> Calling av_parser_parse2
with offset -1, ts:99:99:99.999999999 size 109
0:00:42.490170113 15944 0xfd8630 LOG ffmpeg
gstffmpegdec.c:2669:gst_ffmpegdec_chain:<decoder> parser returned res 109
and size 0, id 15
0:00:42.490186316 15944 0xfd8630 LOG ffmpeg
gstffmpegdec.c:2683:gst_ffmpegdec_chain:<decoder> consuming 0 bytes. id 15
0:00:42.490222354 15944 0xfd8630 LOG GST_SCHEDULING
gstpad.c:4715:gst_pad_push:<parse:src> called chainfunction
&gst_ffmpegdec_chain with buffer 0x7fd0bc171840, returned ok
0:00:42.528915821 15944 0xfd8630 LOG GST_SCHEDULING
gstpad.c:4708:gst_pad_push:<parse:src> calling chainfunction
&gst_ffmpegdec_chain with buffer 0x7fd0bc35ec80, data 0x10f2220, malloc
(nil), ts 99:99:99.999999999, dur 99:99:99.999999999, size 109, offset
18446744073709551615, offset_end 18446744073709551615, caps: video/x-h264,
width=(int)960, height=(int)540, framerate=(fraction)25/1,
parsed=(boolean)true, stream-format=(string)byte-stream,
alignment=(string)au
I've also tried to change a sink to filesink, but the output file is empty,
too.
Perhaps, someone could help me with the problem, maybe I should set more
precise input caps or more buffer metadata. It is quite common use case
when decoding raw H.264 stream, so any advice is particularly useful. My
GStreamer version is 0.10.36.
Thanks in advance!
Alexey Chernov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20121110/ac2c1548/attachment.html>
More information about the gstreamer-devel
mailing list