Note that there are some explanatory texts on larger screens.

plurals
  1. POConvert raw yuv to mp4 crashed on android
    primarykey
    data
    text
    <p>Here is my steps:</p> <ol> <li><p>Decode a jpeg file to rgb565;(Success);</p></li> <li><p>Convert rgb565 to yuv420;(Not sure if it works, function "Bitmap2Yuv420")</p></li> <li><p>Convert yuv420 to mp4. (Crash when call avcodec_open2);</p></li> </ol> <p>And that is the codes:</p> <pre><code>void ADKJpegDecoder::Bitmap2Yuv420(const char * outfilename) { unsigned char *destination = new unsigned char[m_Width * m_Height * m_BytesPerPixel / 2]; unsigned char* rgb = m_RawImage; size_t image_size = m_Width * m_Height; size_t upos = image_size; size_t vpos = upos + upos / 4; size_t i = 0; for (size_t line = 0; line &lt; m_Height; ++line) { if (!(line % 2)) { for (size_t x = 0; x &lt; m_Width; x += 2) { char r = rgb[3 * i]; char g = rgb[3 * i + 1]; char b = rgb[3 * i + 2]; destination[i++] = ((66 * r + 129 * g + 25 * b) &gt;&gt; 8) + 16; destination[upos++] = ((-38 * r + -74 * g + 112 * b) &gt;&gt; 8) + 128; destination[vpos++] = ((112 * r + -94 * g + -18 * b) &gt;&gt; 8) + 128; r = rgb[3 * i]; g = rgb[3 * i + 1]; b = rgb[3 * i + 2]; destination[i++] = ((66 * r + 129 * g + 25 * b) &gt;&gt; 8) + 16; } } else { for (size_t x = 0; x &lt; m_Width; x += 1) { char r = rgb[3 * i]; char g = rgb[3 * i + 1]; char b = rgb[3 * i + 2]; destination[i++] = ((66 * r + 129 * g + 25 * b) &gt;&gt; 8) + 16; } } } ADKVideoEncoder::getInstance()-&gt;startEncodeVideo(destination); delete[] destination; </code></pre> <p>}</p> <pre><code>void ADKVideoEncoder::startEncodeVideo(unsigned char* rawDatas) { AVFormatContext* oc; AVOutputFormat* fmt; AVStream* video_st; AVCodecContext* c; double video_pts; uint8_t* video_outbuf; AVFrame* picture; int size; int ret; int video_outbuf_size; const char* filename = "/sdcard/test.mpg"; av_register_all(); fmt = av_guess_format(NULL, filename, NULL); oc = avformat_alloc_context(); oc-&gt;oformat = fmt; snprintf(oc-&gt;filename, sizeof(oc-&gt;filename), "%s", filename); video_st = NULL; if (fmt-&gt;video_codec != CODEC_ID_NONE) { video_st = av_new_stream(oc, 0); c = video_st-&gt;codec; c-&gt;codec_id = fmt-&gt;video_codec; c-&gt;codec_type = AVMEDIA_TYPE_VIDEO; c-&gt;bit_rate = 400000; c-&gt;width = 320; c-&gt;height = 480; c-&gt;time_base.num = 1; c-&gt;time_base.den = 1; c-&gt;gop_size = 12; c-&gt;pix_fmt = PIX_FMT_YUV420P; c-&gt;max_b_frames = 0; if (!strcmp(oc-&gt;oformat-&gt;name, "mp4") || !strcmp(oc-&gt;oformat-&gt;name, "mov") || !strcmp(oc-&gt;oformat-&gt;name, "3gp")) { c-&gt;flags |= CODEC_FLAG_GLOBAL_HEADER; } } av_dump_format(oc, 0, filename, 1); if (video_st) { AVCodec* codec = avcodec_find_encoder(c-&gt;codec_id); if (!codec) { return; } AVDictionary *optionsDict = NULL; if (avcodec_open2(c, codec, &amp;optionsDict) &lt; 0) { return; } if (!(oc-&gt;oformat-&gt;flags &amp; AVFMT_RAWPICTURE)) { video_outbuf_size = 20000; video_outbuf = (uint8_t*) av_malloc(video_outbuf_size); } picture = avcodec_alloc_frame(); size = avpicture_get_size(c-&gt;pix_fmt, c-&gt;width, c-&gt;height); avpicture_fill((AVPicture*) picture, rawDatas, c-&gt;pix_fmt, c-&gt;width, c-&gt;height); } if (!(fmt-&gt;flags &amp; AVFMT_NOFILE)) { if (avio_open(&amp;oc-&gt;pb, filename, AVIO_FLAG_WRITE) &lt; 0) { return; } } avformat_write_header(oc, 0); if (video_st) { video_pts = (double) (video_st-&gt;pts.val * video_st-&gt;time_base.num / video_st-&gt;time_base.den); } else { video_pts = 0.0; } if (!video_st/* || video_pts &gt;= 5.0*/) { return; } c = video_st-&gt;codec; size = c-&gt;width * c-&gt;height; picture-&gt;data[0] = rawDatas; picture-&gt;data[1] = rawDatas + size; picture-&gt;data[2] = rawDatas + size * 5 / 4; if (oc-&gt;oformat-&gt;flags &amp; AVFMT_RAWPICTURE) { AVPacket pkt; av_init_packet(&amp;pkt); pkt.flags |= AV_PKT_FLAG_KEY; pkt.stream_index = video_st-&gt;index; pkt.data = (uint8_t*) picture; pkt.size = sizeof(AVPicture); ret = av_write_frame(oc, &amp;pkt); } else { int out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture); if (out_size &gt; 0) { AVPacket pkt; av_init_packet(&amp;pkt); pkt.pts = av_rescale_q(c-&gt;coded_frame-&gt;pts, c-&gt;time_base, video_st-&gt;time_base); if (c-&gt;coded_frame-&gt;key_frame) { pkt.flags |= AV_PKT_FLAG_KEY; } pkt.stream_index = video_st-&gt;index; pkt.data = video_outbuf; pkt.size = out_size; ret = av_write_frame(oc, &amp;pkt); } } if (video_st) { avcodec_close(video_st-&gt;codec); av_free(picture); av_free(video_outbuf); } av_write_trailer(oc); for (int i = 0; i &lt; oc-&gt;nb_streams; i++) { av_freep(&amp;oc-&gt;streams[i]-&gt;codec); av_freep(&amp;oc-&gt;streams[i]); } if (!(fmt-&gt;flags &amp; AVFMT_NOFILE)) { avio_close(oc-&gt;pb); } av_free(oc); </code></pre> <p>}</p> <p>So can anyone find out the problem? Thanks very much!;</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload